ts高级类型部分个人觉得非常有意思,我从各大平台借鉴了一些比较有意思的类型体操(有修改),一起来练习:
一、模板类型
ts类型实现 js trim方法
type TrimFront<T extends string> = T extends `${' '}${infer K}` ? TrimFront<K> : T
type A = TrimFront<' Hello'> //Hello
/*
Trim 实现了一个可以去除字符串前面的所有空格,如果T前面含有空格则递归删除前面的空格,
直到可以直接返回出去
*/
有了以上的案例,我们可以实现一个Trim:
type TrimFront<T> = T extends `${' '}${infer Res}` ? TrimFront<Res> : T
type TrimTail<T> = T extends `${infer Res}${' '}` ? TrimTail<Res> : T
type Trim<T> = TrimTail<TrimFront<T>>
type A =Trim<' Hello World '> //"Hello World"
/*
定义一个去除头部类型,再定义一个去除尾部空格的类型
最后以嵌套的方式就可以出来
*/
实现js replace方法
type Replace<T extends string,K extends string,U extends string> =
T extends `${infer Left}${K}${infer Right}` ? `${Left}${U}${Right}` : T
/*
注意:这里的K,U都要声明上限string,否则使用到K、U的地方都会报错,之前我一直在这里报错
*/
二、递归
关于ts类型递归本质用法和js等其他语言的递归完全一致,来看两个例子:
推断Promise类型
例如:
Promise<number> --> number Promise<string[]> --> string[] Promise<Promise<number[]>> --> number[]
type MyAwait<T extends Promise<unknown>>=
T extends Promise<infer U> ?
(U extends Promise<unknown> ? MyAwait<U> : U) : T
实现字符串反转
// type Pop<T extends string> = T extends `${infer First}${infer Res}` ? Res : T
type Reverse<T extends string,R extends string = ''> =
T extends `${infer First}${infer Res}` ? Reverse<Res,`${First}${R}`> : R
type A = Reverse<'Hello World'> //dlroW olleH
/*
像我们很多思路在类型中需要有一些变换,在这里为了实现字符串反转,
使用一个R泛型去接收反转结果,这个结果是需要递归接收的,
我们只需要将T中的第一个字符赋给R,再让剩下的Res作为新T传入递归,
并且保证每次的First一定要插入在R的最前面
*/
最后再来看一个递归创建数组的类型:
type CreateArray<T extends unknown,L extends number,Arr extends T[] = []> = Arr['length'] extends L ?
Arr : CreateArray<T,L,[T,...Arr]>
后续有机会还会再更新一些类型体操!