Для чего используется infer в TypeScript
Что проверяют
Умеете ли вы писать свои утилитные типы, а не только пользоваться готовыми. Следом обычно просят написать ReturnType или Awaited с нуля и спрашивают, почему infer нельзя использовать вне условного типа.
Как отвечать
infer объявляет переменную типа внутри условия extends условного типа: TypeScript сопоставляет тип с шаблоном и подставляет найденную часть. Вне этой ветки ключевое слово не работает.
type MyReturn<T> = T extends (...args: any[]) => infer R ? R : never;
type Item<T> = T extends readonly (infer U)[] ? U : never;
type Split<S> = S extends `${infer Head}/${infer Rest}` ? [Head, ...Split<Rest>] : [S];Где это встречается во фронтенде:
- встроенные утилиты:
ReturnType,Parameters,InstanceType,Awaitedнаписаны черезinfer, и полезно знать, как они устроены; - типы из существующих функций:
Awaited<ReturnType<typeof fetchUser>>даёт тип ответа API без ручного дублирования интерфейса; - шаблонные литеральные типы:
Splitиз примера раскладывает путь роутера на сегменты, так же достают параметры вида:id; - ограничение выведенного типа:
infer N extends numberпроверяет найденную часть прямо в шаблоне, без второго условного типа.
Покажите и поведение по умолчанию: условный тип с голым параметром распределяется по объединению. Для type IsStr<T> = T extends string ? true : false запись IsStr<string | number> даст boolean. Если распределение не нужно, параметр оборачивают в кортеж: [T] extends [string].
Где спотыкаются
Пытаются написать infer в обычном дженерике или в теле интерфейса. Компилятор отвечает ошибкой: infer допустим только в extends-части условного типа.
Забывают про перегрузки: ReturnType у перегруженной функции берёт последнюю сигнатуру, и тип получается не тот, что ожидали.
Изобретают велосипед: пишут свой PropsOf через infer, когда в React уже есть ComponentProps<typeof Button>. Умение применить infer ценно, но готовые утилиты тоже надо знать.