#javascript #typescript
#javascript #typescript
Вопрос:
Пример:
function useCallback(fn) {
return fn;
}
type ApiData = {
'/user': { user: any },
'/post': { post: any },
};
function useApi<Path extends keyof ApiData>(
path: Path,
opts: {
cb?: (data: ApiData[Path]) => void,
},
) {}
useApi('/user', { cb: ({ user }) => null }); // ok
useApi('/user', { cb: ({ post }) => null }); // Property 'post' does not exist on type '{ user: any; }'
useApi('/user', { cb: useCallback(({ user }) => null) }); // ok
useApi('/user', { cb: useCallback(({ post }) => null) }); // should have error
В этом примере, без useCallback
, TS смог автоматически определить тип типа аргумента обратного вызова. Однако при useCallback
этом он теряет эту способность.
Интересно, что если я сделаю cb
свойство обязательным, то TS сможет определить тип аргумента:
function useApi<Path extends keyof ApiData>(
path: Path,
opts: {
cb: (data: ApiData[Path]) => void, // <- removed the "?"
},
) {}
useApi('/user', { cb: useCallback(({ post }) => null) }); // Property 'post' does not exist on type '{ user: any; }'
Как я могу заставить TS выводить аргумент обратного вызова?
Комментарии:
1. С точно такой же проблемой. Не уверен, почему это было отклонено. Каким-то образом вывод типа перестает работать, когда параметр является необязательным.
Ответ №1:
Это не имеет значения с ?
необязательным оператором
Анализатор Typescript правильно определяет, что это за типы.
Поскольку вы указали первый параметр функции useApi как '/user'
, он не будет работать.
Измените его на,
useApi('/post', { cb: useCallback(({ post }) => null) });
Это сработало бы.
Комментарии:
1. В этом случае OP ожидает ошибку, см. // должен иметь комментарий к ошибке . Ошибка не отображается, поскольку тип обратного вызова расширен