作用:用来做类型推断
使用场景:声明类型变量需要和条件类型配合使用
type UnpackedArray<T> = T extends (infer U)[] ? U : T
type T0 = string[]
type U0 = UnpackedArray<T0> //string

限制1:只能在条件类型的 extends 子句中使用
// 错误
type Wrong1<T extends (infer U)[]> = T[0]
type Wrong<T> = (infer U)[] extends T ? U : T
限制2:只能在条件类型的 true 分支可用
// 找不到名称 U
type Wrong3<T> = T extends (infer U)[] ? T : U
返回联合类型
type PropertyType<T> = T extends {id: infer U; name: infer U} ? U : T
type User = {
id: number
name: string
}
type U4 = PropertyType<User> // string | number
返回交叉类型
type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never
type U5 = Bar<{a: (x: string) => void, b: (x: number) => void}> // string & number => never
为 infer type 添加可选的 extends 子句
type FirstIfString<T> = T extends [infer S, ...unknown[]] ? S extends string ? S : never : never
简化为
type FirstIfString<T> = T extends [infer S extends string, ...unknown[]] ? S : never
infer 解构
- 对于数组
type B<S extends unknown[]> = S extends [infer First, ...infer Reset] ? First : never
type B1 = B<[1,2,3]> // 1
- 对于字符串
第一个 infer 就是这个字符串的第一项
type A<S extends string> = S extends `${infer First}${infer Second}` ? First : S
type z = A<'abc'> // 'a'
type A1<S extends string> = S extends `${infer First}${infer Second}` ? Second : S
type z1 = A1<'abc'> // 'bc'
获取匹配的字符串
正常情况下我们匹配一个字符串或者数组啥的,主要就是包括三部分,头部匹配、中部匹配和尾部匹配,所以意味着我们要用三个类型占位符来匹配我们传入的类型,然后我们主要匹配的类型要在中间,这样才会有三种情况,比如下面的匹配 S 里的 From
1). 构造三个占位类型 Start From End
2). 要匹配的类型放在中间 也就是 From 在中间 ${infer Start}${From}${infer End}
3). 如果 From 匹配到的是头部,那么 Start 就是一个空的字符串
4). 如果 From 匹配的是中部,那么 Start 就是前部分 From 就是中部 End 就是尾部
5). 如果 From 匹配的是尾部,那么 Start 就是除 From 外的前部分,End 就是空字符
type B<S extends string, From extends string> = S extends `${infer Start}${From}${infer End}`
? [Start, From, End]
: never
type C = B<'foobarbar', 'foo'> // 头部匹配 ["", "foo", "barbar"]
type C1 = B<'foobarbar', 'bar'> // 中部匹配 ["foo", "bar", "bar"]
type C2 = B<'foobaruuu', 'uuu'> // 尾部匹配 ["foobar", "uuu", ""]
网友评论