在类型工具学习中,我们已经接触过类型别名中的泛型,比如类型别名如果声明了泛型坑位,那其实就等价于一个接受参数的函数:

    1. type Factory<T> = T | number | string;

    上面这个类型别名的本质就是一个函数,T 就是它的变量,返回值则是一个包含 T 的联合类型,我们可以写段伪代码来加深一下记忆:

    1. function Factory(typeArg){
    2. return [typeArg, number, string]
    3. }

    类型别名中的泛型大多是用来进行工具类型封装,比如我们在上一节的映射类型中学习的工具类型:

    1. type Stringify<T> = {
    2. [K in keyof T]: string;
    3. };
    4. type Clone<T> = {
    5. [K in keyof T]: T[K];
    6. };

    Stringify 会将一个对象类型的所有属性类型置为 string ,而 Clone 则会进行类型的完全复制。我们可以提前看一个 TypeScript 的内置工具类型实现:

    1. type Partial<T> = {
    2. [P in keyof T]?: T[P];
    3. };

    工具类型 Partial 会将传入的对象类型复制一份,但会额外添加一个?,还记得这代表什么吗?可选,也就是说现在我们获得了一个属性均为可选的山寨版:

    1. interface IFoo {
    2. prop1: string;
    3. prop2: number;
    4. prop3: boolean;
    5. prop4: () => void;
    6. }
    7. type PartialIFoo = Partial<IFoo>;
    8. // 等价于
    9. interface PartialIFoo {
    10. prop1?: string;
    11. prop2?: number;
    12. prop3?: boolean;
    13. prop4?: () => void;
    14. }

    类型别名与泛型的结合中,除了映射类型、索引类型等类型工具以外,还有一个非常重要的工具:条件类型。我们先来简单了解一下:

    1. type IsEqual<T> = T extends true ? 1 : 2;
    2. type A = IsEqual<true>; // 1
    3. type B = IsEqual<false>; // 2
    4. type C = IsEqual<'linbudu'>; // 2

    在条件类型参与的情况下,通常泛型会被作为条件类型中的判断条件(T extends Condition,或者 Type extends T)以及返回值(即 : 两端的值),这也是我们筛选类型需要依赖的能力之一。