infer

infer关键字用于在类型表达式中声明局部变量,充当占位符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 如果是数组类型,就返回数组元素的类型,否则,传入什么类型就返回什么类型

// 一般的写法
// type Type<T> = T extends Array<any>? T[number]:T

// infer简化后的写法
// U并不是泛型,它相当于一个占位符,在此处会读取Array中的类型
type Type<T> = T extends Array<infer U>? U: T

type A = Type<string|number> // string|number
type B = Type<(string|number)[]> // string|number


type Arr<T> = T extends Array<infer U>? U: never

type C = Arr<[string,number]> // string | number
type D = Arr<string> // never

infer类型提取

提取头部元素

  1. 泛型T被约束为只能是数组类型
  2. 通过infer提取第一个元素的类型First,后面的元素则是任意类型
  3. 返回局部变量First
1
2
3
4
5
6
type Arr = [1,1,4,5,1,4]
type First<T extends any[]> = T extends [infer First,...any[]]? First: []
type a = First<Arr> // 1

// 同理,这是提取尾部元素
type Last<T extends any[]> = T extends [...any[],infer Last]? Last: []

剔除头部元素

  1. 泛型T被约束为只能是数组类型
  2. 第一个元素的类型不用管,通过infer提取剩余元素的类型Rest
  3. 返回局部变量Rest
1
2
3
4
5
6
type Arr = [1,1,4,5,1,4]
type First<T extends any[]> = T extends [unknown,...infer Rest]? Rest: []
type a = First<Arr> // [1, 4, 5, 1, 4]

// 同理,这是剔除尾部元素
type Last<T extends any[]> = T extends [...infer Rest,unknown]? Rest: []

infer递归

1
2
3
4
type Arr = [1,2,3,4]
type Reverse<T extends any[]> =
T extends [infer First, ...infer rest]? [...Reverse<rest>, First]: T
type Res = Reverse<Arr> // [4, 3, 2, 1]