TypeScript 的 extends 条件类型
这是 TS2.8 版本中推出的特性,此能力让类型定义变的更加灵活,需要注意:extends 运用在 type 和 class 中时完全是两种作用的效果。
条件类型是一种 条件表达式 进行类型的关系检测
分为以下几种类型检测
简单值(原始值)的匹配
1
2
3
4
5
6相当于是匹配两值是否相等
type Equal<X, Y> = X extends Y ? true : false;
type Num = Equal<1, 1>; // true
type Str = Equal<'a', 'a'>; // true
type Boo = Equal<true, false>; // false简单的类型匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18匹配是否属于某个基本类型
type isStr<T> = T extends string ? true : false;
isStr<"2"> // true
isStr<2> // false
当然,我们也可以像写三元表达式一样进行类型匹配
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 A = TypeName<"a">; // "string"
type B = TypeName<true>; // "boolean"
type C = TypeName<() => void>; // "function"
type D = TypeName<string[]>; // "object"判断联合类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23type A<A, B> = A extends B ? 'true' : 'false'; // 'true'
type B = 'x';
type C = 'x' | 'y';
type D = A<B, C> // 'true'
看上去没什么问题,那是因为我们传入了一个明确的判断值,肯定为 'true'。
但是当传入的A是联合类型的话,返回的值则大径相庭
type B = 'x' | 'y';
type C = 'x' | 'y';
type D = A<B, C> // 'true' 当两个联合一样返回是'true'
type B = 'x' | 'y' | 'z';
type C = 'x' | 'y';
type D = A<B, C> // 'true' | 'false' 两个联合类型不一样时,返回的是 'true'|'false'
其实是因为Ts的一个 *分布条件类型* 特性, T extends U ? X : Y,当 T 是 A|B 时候,会拆分为A extends U ? X : Y | B extends U ? X : Y。
上面被转换为:'x' extends C ? 'true' : 'false' | 'y' extends C ? 'true' : 'false' | 'z' extends C ? 'true' : 'false' ==> 'true' | 'true' | 'false' ==> 'true' | 'false'
通过这个特性,我们可以实现Exclude过滤功能的函数:
type Exclude<T, U> = T extends U ? never : T;
type Values = Exclude<"x" | "y" | "z", "x">; // 'y' | 'z'
最后更新: 2021年02月08日 19:08