不知道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