Ключевое слово infer — это одна из самых мощных возможностей в Conditional Types (условных типах). Оно позволяет объявить переменную типа внутри условия extends, чтобы «вытащить» (вывести) тип из другой структуры.
Чаще всего infer используется для:
- Получения типа возвращаемого значения функции (
ReturnType). - Получения типа элементов массива.
- «Распаковки» промисов или других оберток.
Синтаксис выглядит так: T extends SomeType. Если TypeScript может сопоставить T с шаблоном, он запишет выведенный тип в U, и мы сможем использовать его в ветке «true».
- Модуль 1: Введение в TypeScript
- Модуль 2: Примитивные типы
- Модуль 3: Специальные типы
- Модуль 4: Массивы
- Модуль 5: Кортежи (Tuples)
- Модуль 6: Объекты
- Модуль 7: Функции
- Модуль 8: Union типы
- Модуль 9: Литеральные типы
- Модуль 10: Type Aliases
- Модуль 11: Интерфейсы
- Модуль 12: Type Guards и Narrowing
- Модуль 13: Enums
- Модуль 14: Классы
- Модуль 15: Generics — основы
- Модуль 16: Generics — ограничения
- Модуль 17: Utility Types — базовые
- Модуль 18: Utility Types — работа с Union
- Модуль 19: Utility Types — функции
- Модуль 20: Type Assertions
- Модуль 21: Keyof и Typeof операторы
- Модуль 22: Mapped Types
- Модуль 23: Conditional Types
- Основы Conditional Types.
- Distributive Conditional Types.
- Ключевое слово infer.
- Модуль 24: Discriminated Unions
- Модуль 25: Модули и типы
- Модуль 26: Declaration Files
- Модуль 27: Типизация асинхронного кода
- Модуль 28: Практические паттерны
1. Структура infer
В условном типе TypeScript разметьте ключевые компоненты, связанные с использованием ключевого слова infer. Определите, где находится ключевое слово infer, имя новой переменной типа, и где эта переменная используется в ветке true условного типа.
type ReturnType<T> = T extends (...args: any[]) => {{infer~|~t1}} {{R~|~t2}} ? {{R~|~t3}} : any;2. Написание Unpacked
В этом задании вам нужно создать условный тип Unpacked, который извлекает тип элемента из массива. Используйте ключевое слово extends для проверки условия, infer для вывода типа элемента и синтаксис массива для завершения условного типа. Заполните пропуски так, чтобы тип Unpacked
type Unpacked<T> = T input1S (input2S U)input3S ? U : T;
// Примеры использования
type StringArray = string[];
type StringType = Unpacked<StringArray>; // string
type NumberArray = number[];
type NumberType = Unpacked<NumberArray>; // number3. Типы infer
Перед вами несколько примеров условных типов TypeScript с использованием ключевого слова `infer`. Распределите их по двум категориям: те, где `infer` извлекает тип аргумента функции, и те, где `infer` извлекает тип возвращаемого значения функции. Обратите внимание на контекст, в котором используется `infer` — внутри условного типа после `extends`, где проверяется соответствие шаблону функции.
type FirstParam<T> = T extends (first: infer F, ...rest: any[]) => any ? F : never;type Return<T> = T extends (...args: any[]) => infer R ? R : never;type Params<T> = T extends (...args: infer P) => any ? P : never;type SecondParam<T> = T extends (first: any, second: infer S, ...rest: any[]) => any ? S : never;type PromiseReturn<T> = T extends (...args: any[]) => Promise<infer R> ? R : never;type ConstructorReturn<T> = T extends new (...args: any[]) => infer R ? R : never;4. Логика вывода типа
Проанализируйте TypeScript-код сверху, который определяет условный тип ReturnType и применяет его к нескольким функциям. Восстановите последовательность шагов, описывающих логику работы ReturnType. Шаги снизу перемешаны — расставьте их в правильном порядке, чтобы отразить, как TypeScript выводит тип возвращаемого значения функции.
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never;
function foo(): string { return 'hello'; }
type FooReturn = ReturnType<typeof foo>; // string
function bar(): number { return 42; }
type BarReturn = ReturnType<typeof bar>; // number
function baz() { return true; }
type BazReturn = ReturnType<typeof baz>; // boolean5. Область видимости infer
В этом фрагменте кода TypeScript используется условный тип с ключевым словом infer. Однако переменная, выведенная с помощью infer, используется в ложной ветке условного типа, что запрещено правилами области видимости infer. Найдите и исправьте ошибку, переместив использование переменной в истинную ветку.
type GetType<T> = T extends Promise<infer U> ? string : U;// Ошибка: U виден только в true-ветке6. Распаковка Promise
Соберите утилитный тип на TypeScript, который извлекает внутренний тип значения из Promise. Используйте ключевое слово infer в условном типе. Из предложенных строк соберите корректное определение типа, игнорируя лишние строки, которые не относятся к решению задачи.
type UnwrapPromise<T> = T extends Promise<infer Value> ? Value : never;type PromiseType<T> = T extends Promise<T> ? T : never; T extends infer U ? U : nevertype ExtractPromise<T> = Promise<T>;7. Результат вывода
В данном задании вам предстоит проанализировать условный тип TypeScript, использующий ключевое слово infer. Изучите предоставленный код и определите, какой тип будет присвоен переменной Result. Введите ответ в виде одного слова — названия типа (например, string, number, boolean и т.д.) без кавычек и дополнительных символов.
type Unpack<T> = T extends (infer U)[] ? U : T;
type Result = Unpack<string[]>;8. Infer в аргументах
В этом задании вам предстоит заполнить пропуски в определении условного типа `MyParameters`, который должен извлекать типы параметров функции. Выберите из выпадающего списка подходящие элементы, чтобы тип `MyParameters` был эквивалентен встроенному типу `Parameters`. Обратите внимание на использование ключевого слова `infer` и типов `any`, `never`.
type MyParameters<T> = T extends (...args: input1S) => input2S ? input3S : input4S;