关于TypeScript中的infer的用法理解
提到TypeScript中的infer关键字,我们需要联想到【条件类型】(Conditional Types)
具体可以查看:https://www.typescriptlang.org/docs/handbook/2/conditional-types.html
SomeType extends OtherType ? TrueType : FalseType;
相关的条件类型示例
1.
interface Animal { live(): void; } interface Cat extends Animal { sleep(): void; } type CondType = Cat extends Animal ? number : string; // CondType => number
2.
interface IdLabel { id: number; } interface NameLabel { name: string; } type NameOrId<T extends number | string> = T extends number ? IdLabel : NameLabel; function createLabel <T extends number | string>(idOrName: T): NameOrId<T> { throw "unimplemented"; }
3.
type MessageOf<T extends { message: unknown }> = T['message']; interface Email { message: string; } type EmailMessageContents = MessageOf<Email>; // EmailMessageContents => string
4.
type Flatten<T> = T extends any[] ? T[number] : T; type Str = Flatten<string[]>; // Str => string
type Num = Flatten<number[]>; // Num => number
使用类型约束来条件性地选择、提取目标类型是相对常规且比较容易的。
infer 类型推导
条件类型还提供了一种使用infer关键字在类型比较的true分支中进行目标类型推断的方法。
(可以将infer当作一种标记符,后续可以得到其标记的类型)
示例
type Flatten<Type> = Type extends Array<infer Item> ? Item : Type; type Str = Flatten<string[]>; // Str => string type Num = Flatten<number[]>; // Num => number
type GetReturnType<T> = T extends (...args: never[]) => infer Return ? Return : never; type Num = GetReturnType<() => number>; // Num => number type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>; // Bools => boolean[]
type ToArray<T> = T extends any ? T[] : never; type StrArrOrNumArr = ToArray<string | number>; // StrArrOrNumArr => string[] | number[]; type ToArrayNonDist<T> = [T] extends [any] ? T[] : never; type StrArrOrNumArr = ToArrayNonDist<string | number>; // StrArrOrNumArr => (string | number)[]
end.