体操就是做锻炼,给你的大脑做锻炼
有没有什么实际的意义呢?我觉得没有,工作中用不到,只是为了锻炼而已
if else
JS:
1 2 3 4 5
| if (A <= B) { return true } else { return false }
|
TS:
1 2 3
| type A = 1 type B = 1 | 2 type Result = A extends B ? true : false
|
加一点复杂
JS:
1 2 3 4 5
| if (A<= B && C<= D) { ... } else { ... }
|
TS:
1 2 3 4 5 6 7 8 9 10 11 12
| type A = 1 type B = 1 | 2 type C = 3 type D = 3 | 4
type Result = A extends B ? C extends D ? 'true, true' : 'true, false' : C extends D ? 'false, true' : 'false, false'
|
看的出来,没有 if else,TS 的代码很难看
这就是 TS 类型体操的蛋疼之处,并不是逻辑复杂,而是看起来复杂
判断是否是元组
1 2 3 4
| type A = [] type IsEmptyArray<T exxtends unknown[]> = Arr['length'] extends 0 ? true : false
type Result = IsEmptyArray<A>
|
infer
还是以上面判断是否为元组的栗子:
1 2 3 4
| type A = [] type IsEmptyArray<T exxtends unknown[]> = Arr extends [...inter X[], inter D] ? true : false
type Result = IsEmptyArray<A>
|
这里用 inter “引用”(可以把它当做 var),等价于:
1 2 3 4
| type A = [] type IsEmptyArray<T exxtends unknown[]> = Arr extends [...unknown[], unknown] ? true : false
type Result = IsEmptyArray<A>
|
递归
等价于 for 循环,但是在 TS 中递归有层数限制(不多),有兴趣动手可以测试一下
1 2 3 4 5 6 7
| type A = ['ji', 'ni', 'tai', 'mei'] type Reverse<Arr extends unknown[]> = Arr extends [...infer Rest, inter Last] ? [Last, ...Reverse<Rest>] : Arr
tytpe Result = Reverse<A>
|
模式匹配
合并元组
1 2 3 4
| type A = [1, 2] type B = [3, string]
type C = [...A, ...B]
|
获取元组的最后一项
1 2 3 4
| type Arr = [1, 2, 3, 4] type Last<T extends unknown[]> = T extends [...Rest, Last] ? Last : never
type L = Last<Arr>
|
模版字符串
1 2 3 4 5
| type A = 'A' type B = 'B' type C = 'C'
type X = `${A} ${B} ${C}`
|
没错,模版字符串在 TS 中也能使用
怎么获取字符串的第一个?没错还是用模式匹配
1 2 3 4 5
| type A = 'ji ni tai mei'
type First<T extends string> = T extends `${inter First}${string}` ? F : never
type Result = First<A>
|
那怎么获取字符串的最后一项呢?似乎有点麻烦,也许可能用递归能实现
但是这个时候就需要换一种思路了,获取元组的最后一项非常简单,那么直到能把字符串转换成元组就好了(体操最重要的就是思路!)
1 2 3 4 5
| type A = 'ji ni tai mei' type LastOfArr<T extends unknown[]> = T extends [...inter _, inter Last] ? Last : never
type StringToArr<T extends string> = T extends `${inter F}${inter Rest}` ? [F, ...StringToArr<Rest>] : [] type LastOfString = LastOfArr<StringToArr<A>>
|
相应的也能转换成联合类型
1 2 3 4 5
| type A = 'ji ni tai mei' type StringToUnion<T extends string> = T extends `${inter F}${inter Rest}` ? F | StringToUnion<Rest> : never
type Result = StringToUnion<A>
|