条件类型 是 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}
