type tuple = [1, 2,3]
数组类型的重新构造
Push
type Push<Arr extends unknown[], Ele> = [...Arr, Ele]
数组和元组的区别: 数组类型是指任意多个同一类型的元素构成的,比如number[], Array< number >, 而元组则是数量固定,类型可以不同的元素构成的,比如[1, true, 'e']
Unshift
type Unshift<Arr extends unknown[], Ele> = [Ele, ...Arr]
Zip
type tuple1 = [1, 2]
type tuple2 = ['guang', 'dong']
// 合并成
type tuple3 = [[1, 'guang'], [2, 'dong']]
type Zip<One extends [unknown, unknown], Other extends [unknown, unknown]> =
One extends [infer OneFirst, infer OneSecond] ?
Other extends [infer OtherFirst, infer OtherSecond] ?
[[OneFirst, OtherFirst], [OneSecond, OtherSecond]] : [] : []
type ZipResult = Zip<[1, 2], ['guang', 'dong']>
// [[1, "guang"], [2, "dong"]]
合并任意个元素的元组
type Zip2<One extends unknown[], Other extends unknown[]> =
One extends [infer OneFirst, ...infer OneRest] ?
Other extends [infer OtherFirst, ...infer OtherRest] ?
[[OneFirst, OtherFirst], ...Zip2<OneRest, OtherRest>] : [] : []
type ZipResult2 = Zip2<[1,2,3,4,5], ['guang', 'dong', 'is', 'best', 'friend']>
// [[1, "guang"], [2, "dong"], [3, "is"], [4, "best"], [5, "friend"]]
字符串类型的重新构造
CapitalizeStr
type CapitalizeStr<Str extends string> =
Str extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : Str
type CapitalizeResult = CapitalizeStr<'guang'> // "Guang"
CamelCase
实现dong_dong_dong 到dongDongDong
type CamelCase<Str extends string> =
Str extends `${infer Left}_${infer Right}${infer Rest}`
? `${Left}${Uppercase<Right>}${CamelCase<Rest>}`
: Str
type CamelCaseResult = CamelCase<'dong_dong_dong'> // "dongDongDong"
DropSubStr
删除字符串中的某个子串
type DropSubStr<Str extends string, SubStr extends string> =
Str extends `${infer Prefix}${SubStr}${infer Suffix}`
? DropSubStr<`${Prefix}${Suffix}`, SubStr>
: Str
type DropResult = DropSubStr<'dong~~~', '~'> // "dong"
递归复用
递归是把问题分解为一系列相似的小问题,通过函数不断调用自身来解决一个个小问题,直到满足结束条件,就完成了问题的求解。
type DeepPromiseValueType<P extends Promise<unknown>> =
P extends Promise<infer ValueType>
? ValueType extends Promise<unknown>
: never
type DeepPromiseValueType2<T> = T extends Promise<infer ValueType> ? DeepPromiseValueType2<ValueType> : T
ReverseArr
type arr1 =[1,2,3,4,5]
type arr2 = [5,4,3,2,1]
type ReverseArr<Arr extends unknown[]> =
Arr extends [infer One, infer Two, infer Three, infer Four, infer Five]
? [Five, Four, Three, Two, One]
: never;
type ReverseArrResult = ReverseArr<[1,2,3,4,5]> // [5, 4, 3, 2, 1]
type ReverseArr2<Arr extends unknown[]> =
Arr extends [infer First, ...infer Rest] ? [...ReverseArr2<Rest>, First] : Arr;
type ReverseArrResult2 = ReverseArr2<[1,2,3,4,5]> // [5, 4, 3, 2, 1]
Includes
type Includes<Arr extends unknown[], FindItem> =
Arr extends [infer First, ...infer Rest]
? isEqual<First, FindItem> extends true
? true
: Includes<Rest, FindItem>
: false
type BuildArray<Length extends number, Ele = unknown, Arr extends unknown[] = []> =
Arr['length'] extends Length ? Arr : BuildArray<Length, Ele, [...Arr, Ele]>
type BuildArrayResult = BuildArray<5, 1,[2]> // [2, 1, 1, 1, 1]
type BuildArray2<Length extends number, Ele = unknown, Arr extends unknown[] = []> =
Arr['length'] extends Length ? Arr : BuildArray<Length, Ele, [...Arr, Ele]>
type BuildArrayResult2 = BuildArray2<3, 1> // [1, 1, 1]
type Add<Num1 extends number, Num2 extends number> =
[...BuildArray2<Num1>, ...BuildArray2<Num2>]['length']
type AddResult = Add<32, 25> // 57
type Substract<Num1 extends number, Num2 extends number> =
BuildArray<Num1> extends [...arr1: BuildArray<Num2>, ...arr2: infer Rest]
? Rest['length']
: never
type SubstractResult = Substract<33, 12> // 21