条件类型 是 ts 中一个非常高级的内容。建议好好读更新日志来学习。
我主要讲一下我实际中用到的情况:
条件判断
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type T0 = TypeName<string>; // "string"
type T1 = TypeName<"a">; // "string"
type T2 = TypeName<true>; // "boolean"
type T3 = TypeName<() => void>; // "function"
type T4 = TypeName<string[]>; // "object"
distributive conditional types
注意一下,如果我们输入的参数是 union type,则会被拆开
type T10 = TypeName<string | (() => void)>; // "string" | "function"
type T12 = TypeName<string | string[] | undefined>; // "string" | "object" | "undefined"
type T11 = TypeName<string[] | number[]>; // "object"
因为对参数的 union 会被 ts 先拆开分别求值
TypeName<string | (() => void)>
TypeName<string> | TypeName<() => void)>
"string" | "function"
如果我们想要保证不被拆开,则我们可以这样子写
type TypeName<T> = [T] extends [string]
? 'string'
: [T] extends [number]
? 'number'
: [T] extends [boolean]
? 'boolean'
: [T] extends [undefined]
? 'undefined'
: [T] extends [Function]
? 'function'
: 'other';
type T0 = TypeName<string>; // "string"
type T1 = TypeName<'a'>; // "string"
type T2 = TypeName<true>; // "boolean"
type T3 = TypeName<() => void>; // "function"
type T4 = TypeName<string[]>; // "other"
type T10 = TypeName<string | (() => void)>; // "other"
type T12 = TypeName<string | string[] | undefined>; // "other"
type T11 = TypeName<string[] | number[]>; // "other"
Type inference in conditional types
我们可以通过 infer 获取类型中的部分结构,组装成新的类型:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
type PromiseType<T extends Promise<any>> = T extends Promise<infer U>
? U
: never;
type T = PromiseType<Promise<{a:number}>> // {a:number}
type Required<T> = { [P in keyof T]-?: T[P] };
type T1 = Required<{a?:number}> // {a:number}