Ts的Extract与类型断言进行对比

122 阅读2分钟

不知道Extract的可以看我之前的笔记,或者自己百度。


class People {
    constructor(public name: string, public age: number) {

    }
}

class ChinesePeople extends People {
    public phone!: string;

    constructor(public name: string, public age: number) {
        super(name, age);
    }
}

Extract泛型约束和类型断言结果对比【父子类】

类型断言

let people: People = new People('芝士小邓', 18);
let people2: ChinesePeople = people as ChinesePeople; // 父类型 断言 子类型 成立

let chinesePhone: ChinesePeople = new ChinesePeople('芝士小邓', 18);
let chinesePhone2: People = chinesePhone as People; // 子类型 断言 父类型 成立

Extract泛型约束

type extractType = Extract<ChinesePeople, People>; // 父类型 约束 子类型 成立 返回 ChinesePeople
type extractType2 = Extract<People, ChinesePeople>; // 子类型 约束 父类型 不成立 返回 never

/*
* 一般情况下子类都会扩展父类的属性 所以都是不成立的,如果想要extractType2成立返回People,那么
* 就要让People和ChinesePeople 属性、方法 全部一样
* */

Extract泛型约束和类型断言【联合类型】

type unionExtractType = Extract<number, string | number>; // number
type unionExtractType2 = Extract<string | number, string | number>; // string | number
type unionExtractType3 = Extract<string | number, string | number | symbol>; // string | number
type unionExtractType4 = Extract<string | number, string>; // string
type unionExtractType5 = Extract<string | number | symbol, string | number>; // string | number

以上代码的解析:

type unionExtractTypeTest = Extract<string | number, string | boolean>; // string
// 第一次:string extends string ? T : never    结果是 string
// 第二次:string extends boolean ? T : never   结果是 never
// 第三次:number extends string ? T : never   结果是 never
// 第四次:number extends boolean ? T : never   结果是 never
// 最后 将结果 合并成联合类型 就是 string

可以自己写一个Extract 例如:
注意:内置的Extract不成立的情况下为never,我这里改成boolean

type myExtract<T, U> = T extends U ? T : boolean;

type unionExtractTypeTest2 = myExtract<string | number, string | boolean>; // string | boolean

Extract泛型约束和类型断言【函数】

type foo1 = (one: string, two: number) => string;
type foo2 = (one: string) => string;

// 函数泛型约束
// 函数类型上的泛型约束 参数类型和返回值类型完全相同的情况下
// 参数多的 extends 参数少的  不成立
// 参数少的 extends 参数多的  成立
type beginType1 = foo1 extends foo2 ? foo1 : never; // never
type beginType2 = foo2 extends foo1 ? foo2 : never; // (one: string) => string

// 使用Extract
type extractTypeFun1 = Extract<foo1, foo2>; // never
type extractTypeFun2 = Extract<foo2, foo1>; // (one: string) => string