# 十二.条件类型
前言
语法: T extends U ? X : Y;
# 1.条件类型基本使用
可以使用extends
关键字和三元表达式,实现条件判断
interface Fish {
name1: string;
}
interface Water {
name2: string;
}
interface Bird {
name3: string;
}
interface Sky {
name4: string;
}
type Condition<T> = T extends Fish ? Water : Sky;
let con1: Condition<Fish> = { name2: "水" };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 2.条件类型分发
let con2: Condition<Fish | Bird> = { name2: "水" };
1
这里会用每一项依次进行分发,最终采用联合类型作为结果,等价于
type c1 = Condition<Fish>;
type c2 = Condition<Bird>;
type c = c1 | c2;
1
2
3
2
3
# 3.内置条件类型
- 1.
Exclude
排除类型:从T中剔除U的类型
type type3 = Exclude<string | number | boolean, undefined | number >
type MyExclude = Exclude<"1" | "2" | "3", "1" | "2">;
1
2
2
原理
type Exclude<T, U> = T extends U ? never : T;
1
- 2.
Extract
抽取类型:提取 T 中可以赋值给 U 的类型
type res = Extract<string | number | boolean, number | string> //type res = string | number
type res1 = Extract<string | boolean, number | string> //type res1 = string
type MyExtract = Extract<"1" | "2" | "3", "1" | "2">;
1
2
3
2
3
原理
type Extract<T, U> = T extends U ? T : never;
1
- 3.
NoNulllable
非空检测:从T中去掉null和undefined
type type9 = NonNullable<string | number | null | undefined> //type type9 = string | number
type MyNone = NonNulllable<"a" | null | undefined>;
1
2
2
原理
type NonNulllable<T> = T extends null | undefined ? never : T;
1
- 4.
ReturnType
:获取函数返回值类型
type type10 = ReturnType<()=> string> //type type10 = string
1
- 5.
Parameters
:获得函数的参数类型组成的元组类型
function say(name: string, age: number, gender: boolean) {}
type res = Parameters<typeof say>; //type res = [name: string, age: number, gender: boolean]
1
2
2
# 4.infer 类型推断
- 1.ReturnType 返回值类型
function getUser(a: number, b: number) {
return { name: "abc", age: 10 };
}
type ReturnType<T> = T extends (...args: any) => infer R ? R : never;
type MyReturn = ReturnType<typeof getUser>;
1
2
3
4
5
2
3
4
5
- 2.Parameters 参数类型
type Parameters<T> = T extends (...args: infer R) => any ? R : any;
type MyParams = Parameters<typeof getUser>;
1
2
2
- 3.ConstructorParameters 构造函数参数类型
class Person {
constructor(name: string, age: number) {}
}
type ConstructorParameters<T> = T extends { new (...args: infer R): any }
? R
: never;
type MyConstructor = ConstructorParameters<typeof Person>;
1
2
3
4
5
6
7
2
3
4
5
6
7
- 4.InstanceType 实例类型
type InstanceType<T> = T extends { new (...args: any): infer R } ? R : any;
type MyInstance = InstanceType<typeof Person>;
1
2
2
# 5.infer 实践
将数组类型转化为联合类型
type ElementOf<T> = T extends Array<infer E> ? E : never;
type TupleToUnion = ElementOf<[string, number, boolean]>;
1
2
2
将两个函数的参数转化为交叉类型
type T1 = { name: string };
type T2 = { age: number };
type ToIntersection<T> = T extends [(x: infer U) => any, (x: infer U) => any]
? U
: never;
type t3 = ToIntersection<[(x: T1) => any, (x: T2) => any]>;
1
2
3
4
5
6
2
3
4
5
6
表示要把 T1、T2 赋予给 x,那么 x 的值就是 T1、T2 的交集。(参数是逆变的可以传父类)
TS 的类型:TS 主要是为了代码的安全性来考虑。所以所有的兼容性问题都要从安全性来考虑!