在类型工具学习中,我们已经接触过类型别名中的泛型,比如类型别名如果声明了泛型坑位,那其实就等价于一个接受参数的函数:
type Factory<T> = T | number | string;
上面这个类型别名的本质就是一个函数,T 就是它的变量,返回值则是一个包含 T 的联合类型,我们可以写段伪代码来加深一下记忆:
function Factory(typeArg){return [typeArg, number, string]}
类型别名中的泛型大多是用来进行工具类型封装,比如我们在上一节的映射类型中学习的工具类型:
type Stringify<T> = {[K in keyof T]: string;};type Clone<T> = {[K in keyof T]: T[K];};
Stringify 会将一个对象类型的所有属性类型置为 string ,而 Clone 则会进行类型的完全复制。我们可以提前看一个 TypeScript 的内置工具类型实现:
type Partial<T> = {[P in keyof T]?: T[P];};
工具类型 Partial 会将传入的对象类型复制一份,但会额外添加一个?,还记得这代表什么吗?可选,也就是说现在我们获得了一个属性均为可选的山寨版:
interface IFoo {prop1: string;prop2: number;prop3: boolean;prop4: () => void;}type PartialIFoo = Partial<IFoo>;// 等价于interface PartialIFoo {prop1?: string;prop2?: number;prop3?: boolean;prop4?: () => void;}
类型别名与泛型的结合中,除了映射类型、索引类型等类型工具以外,还有一个非常重要的工具:条件类型。我们先来简单了解一下:
type IsEqual<T> = T extends true ? 1 : 2;type A = IsEqual<true>; // 1type B = IsEqual<false>; // 2type C = IsEqual<'linbudu'>; // 2
在条件类型参与的情况下,通常泛型会被作为条件类型中的判断条件(T extends Condition,或者 Type extends T)以及返回值(即 : 两端的值),这也是我们筛选类型需要依赖的能力之一。
