Видеоуроки, интерактивный редактор и сохранение прогресса — бесплатно, сразу после входа.
ВойтиСоздать аккаунт — бесплатноЗакончили урок?
Войдите, чтобы отмечать прогресс
Условие T extends (...args: never[]) => infer R проверяет, что T функция, и в тот же момент записывает тип её результата в R. Если проверка прошла, возвращаем R, иначе never.
Аргументы нам не важны, нужно, чтобы под шаблон подошла функция с любыми параметрами. Интуитивно хочется написать unknown[], но тогда функция (a: string) => void не подойдёт: она не умеет принимать «что угодно» первым аргументом.
С параметрами функций совместимость работает наоборот. Функция подходит под шаблон, если может принять то, что шаблон обещает передать. never это тип, у которого нет значений, и любая функция «может принять» массив из never. Поэтому (...args: never[]) подходит под любую функцию.
Встроенный ReturnType решает это по-другому, через any:
infer ловит любую часть типа, не только результат:
Так устроены Parameters, Awaited и InstanceType из стандартной библиотеки. Если встретился сложный тип из библиотеки, который «достаёт» что-то из другого типа, внутри почти наверняка infer.