@GNG999

Почему не получается задать либо один тип либо другой в typescript?

есть тип MobileMegaMenuItem
есть тип LinkItem

я прописал кастомный хук

export const useOpenMenuByHash = (
    data: any,
    action: (data: MobileMegaMenuItem | LinkItem) => void,
    actionRoom: () => void
) => {
    useEffect(() => {
        if (data && data.length > 0) {
            const hashName = window.location.hash.substring(1);
            if (hashName) {
                const found = data.find((el: MobileMegaMenuItem | LinkItem) => {
                    const elField = 'href' in el ? el.href : el.link;
                    return elField?.includes(hashName) && el.id !== 0;
                });
                found && action(found);
                found && actionRoom && actionRoom();
            }
        }
    }, [data]);
};

применю его

useOpenMenuByHash(data, onClick);

выходит ошибка на onClick

Argument of type '(item: LinkItem) => void' is not assignable to parameter of type '(el: LinkItem | MobileMegaMenuItem) => void'.   Types of parameters 'item' and 'el' are incompatible.     Type 'LinkItem | MobileMegaMenuItem' is not assignable to type 'LinkItem'.       Property 'test' is missing in type 'MobileMegaMenuItem' but required in type 'LinkItem'.


Почему в MobileMegaMenuItem нужно прописывать свойства (поля) LinkItem ? я же как раз таки хочу задать либо тип MobileMegaMenuItem со своей структурой либо тип LinkItem со своей структурой

  • Вопрос задан
  • 98 просмотров
Решения вопроса 1
Aetae
@Aetae Куратор тега TypeScript
Тлен
В action ты кладёшь функцию onClick с сигнатурой (item: LinkItem) => void, а требуется (data: MobileMegaMenuItem | LinkItem) => void, , т.е. функция которая умеет работать и с тем и с тем. Подразумевается что onClick как раз не умеет и может привести к ошибке, потому и не даёт.

Используй дженерик чтобы вывести конкретный тип:
export const useOpenMenuByHash = <Data extends MobileMegaMenuItem | LinkItem>(
    data: Data[],
    action: (data: Data) => void,
    actionRoom?: () => void
) => {
  //...
};

useOpenMenuByHash(data, onClick); // ok

Ну или кастуй руками:
useOpenMenuByHash(data, onClick as (d: LinkItem | MobileMegaMenuItem) => void);
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
В ошибке говорится, что callback-функция, первый аргумент в data.find, описана как (LinkItem) => void, а вы пытаетесь подставить туда (LinkItem | MobileMegaMenuItem) => void
Соответственно вам надо менять контракт find.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы