TS并没有循环、所以在我们不确定数组个数、字符串长度的情况下、对象层数不确定,这个时候我们可以选择递归的方式去代替循环、下面学习下递归的案例!
Promise
type p = Promise<Promise<Promise<Record<string,any>>>>;
type GetPromiseValueType<P extends Promise<unknown>> =
P extends Promise<infer ValueType>
? ValueType extends Promise<unknown>
? GetPromiseValueType<ValueType>
: ValueType
: never;
type res = GetPromiseValueType<p>
Array
// 数组反转
type arr = [1,2,3,4,5];
type ArrReverse<Arr extends unknown[], Value extends [] = []> =
Arr extends [infer First, ...infer Rest]
? [...ArrReverse<Rest>, First]
: Arr
type res = ArrReverse<arr> // [5, 4, 3, 2, 1]
// remove
type arr1 = [1,2,3,4,5];
type RemoveItem<Arr extends unknown[], Item> =
Arr extends [infer First, ...infer Rest]
? First extends Item
? RemoveItem<Rest, Item>
: [First, ...RemoveItem<Rest, Item> ]
: Arr
type removeArr = RemoveItem<arr1, 5> // [1, 2, 3, 4]
// 传入数组长度和每个value的值、得到一个完整的数组
type CreateArr<Length extends number, Ele, Arr extends unknown[] = []> =
Arr['length'] extends Length
? Arr
: CreateArr<Length, Ele, [...Arr, Ele]>
type res = CreateArr<5,'test'> // ["test", "test", "test", "test", "test"]
String
type replaceAll<Str extends string, Elm, Join extends string = ''> =
Str extends `${infer First}${infer Rest}`
? First extends Elm
? replaceAll<Rest, Elm, `${Join}`>
: `${First}${replaceAll<Rest, Elm, Join>}`
: Str;
type res = replaceAll<'hhhhunang','h'> // unang
// 字符串反转
type reverseStr<Str extends string> =
Str extends `${infer First}${infer Rest}`
? `${reverseStr<Rest>}${First}`
: Str;
type reverseRes = reverseStr<'huang'> // "gnauh"
映射类型
type DeepReadonly<Obj extends Record<string, any>> = {
readonly [Key in keyof Obj]:
Obj[Key] extends object
? Obj[Key] extends Function
? Obj[Key]
: DeepReadonly<Obj[Key]>
: Obj[Key];
}
type obj = {
name:'zhangsan',
a:{
age:18,
b:{
aa:"s",
getAge:() =>{}
}
},
getName:() =>{
}
}
type res = DeepReadonly<obj>
type res1 = DeepReadonly<obj>['a']
总结
递归可以帮助我们在不确认长度和层数的时候达到循环遍历做逻辑判断!