Ключевое слово infer в TypeScript
infer — это ключевое слово в TypeScript, которое используется для вывода типов внутри условных типов. Оно позволяет TypeScript автоматически выводить типы в зависимости от контекста, делая код более гибким и позволяя избежать дублирования типов.
infer используется в связке с условными типами для определения типа в зависимости от структуры другого типа. Это позволяет сделать код более динамичным и сокращает необходимость в явном указании типа в некоторых ситуациях.
Как работает infer?
Когда вы используете infer, TypeScript может выводить типы, не задавая их явно, основываясь на том, как они используются внутри условного типа. Это позволяет создавать более универсальные и гибкие типы.
Пример использования infer
Вывод типа возвращаемого значения функции
infer часто используется для извлечения типа возвращаемого значения функции из её типа. Это полезно, когда вам нужно получить тип из объекта или функции без явного указания типа.
type ReturnTypeOfFunction<T> = T extends (...args: any[]) => infer R ? R : never;
function getString(): string {
return "Hello, world!";
}
type Result = ReturnTypeOfFunction<typeof getString>; // string
В этом примере, с помощью infer R
, TypeScript выводит тип возвращаемого значения функции getString
, который будет string
.
ReturnTypeOfFunction<T>
— это условный тип, который проверяет, является ли тип T функцией. Если да, то infer R выводит тип возвращаемого значения функции.- Тип
Result
будет равен string, так как функция getString возвращает строку.
Использование infer для работы с массивами
infer также может использоваться для извлечения типа элементов массива.
type ElementType<T> = T extends (infer U)[] ? U : never;
const numbers: number[] = [1, 2, 3];
type NumberType = ElementType<typeof numbers>; // number
Здесь, тип ElementType<T>
проверяет, является ли тип T
массивом. Если это так, infer U
извлекает тип элементов массива (в нашем случае number).
NumberType
будет равноnumber
, так как массивnumbers
содержит элементы типаnumber
.
Условное использование infer в более сложных типах
infer
может быть полезен для извлечения типов в более сложных типах, таких как объекты, классы и другие структуры данных.
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type ResolvedType = UnwrapPromise<Promise<string>>; // string
type NonPromiseType = UnwrapPromise<number>; // number
В этом примере UnwrapPromise<T>
— это условный тип, который извлекает тип, на который ссылается Promise
. Если T
является Promise
, то infer U
извлекает тип, который был обернут в Promise
, в данном случае это string
.
ResolvedType
будет равноstring
, так какPromise<string>
извлекает типstring
.NonPromiseType
остаётся типомnumber
, так какT
не являетсяPromise
.
Когда использовать infer?
- Когда вам нужно извлечь тип из функции или объекта, не указывая его явно.
- Для работы с более сложными типами, такими как массивы, промисы и другие типы, где нужно извлечь типы элементов.
- Для создания универсальных типов с возможностью адаптации к различным ситуациям, что помогает избежать дублирования кода и повышает гибкость.
Рекомендация:
Используйте infer для извлечения типов в условных типах, чтобы сделать код более гибким и избежать дублирования. Это особенно полезно при работе с функциями, массивами и сложными типами.