We cannot recurse tuple with more than 1000 length due to TS limitation
In this example we try to feed a recursion utility RebuildTuple
with 9990 length tuple
type CreateArrayWithLengthX<
LENGTH extends number,
ACC extends unknown[] = [],
> = ACC['length'] extends LENGTH
? ACC
: CreateArrayWithLengthX<LENGTH, [...ACC, 1]>
type Exceed999<
ARR extends 1[],
> = [...ARR['length'] extends 0 ? [] : [...CreateArrayWithLengthX<999>, ...Exceed999<ARR extends [...infer S extends 1[], infer P] ? S : never>]]
// create 9990 length array
type Tuple9990 = Exceed999<CreateArrayWithLengthX<10>>
type RebuildTuple<T extends unknown, ACC extends unknown[] = []> = T extends [infer S, ...infer R] ? RebuildTuple<R, [...ACC, S]> : ACC
type C = RebuildTuple<Tuple9990>
TS will complains
reference:create tuple with more than 1000 length
However we can use the mapped type to loop the tuple:
type RebuildTuple<T extends unknown> ={ [K in keyof T] : T[K] }
playground
no error
let us do further comparison by using it in function generic:
type RebuildTuple<T extends unknown, ACC extends unknown[]= [] >= T extends [infer S, ...infer R] ? RebuildTuple<R,[...ACC,S]>: ACC
type RebuildTuple1<T extends unknown[]> = { [K in keyof T]: T[K] }
type A = RebuildTuple<[1,2,3]>
// ^?
type A1 = RebuildTuple1<[1,2,3]>
// ^?
const abc=<T extends unknown[]>(v:T extends never ? T : RebuildTuple<T>)=>{}
const abc1=<T extends unknown[]>(v:T extends never ? T : RebuildTuple1<T>)=>{}
abc([1,2,3])
//^?
abc1([1,2,3])
//^?
It can't infer the type, what is wrong?
This is because we forgot to narrow the type in RebuildTuple1
down to a tuple
type RebuildTuple<T extends unknown, ACC extends unknown[]= [] >= T extends [infer S, ...infer R] ? RebuildTuple<R,[...ACC,S]>: ACC
type RebuildTuple1<T extends unknown[]> = T extends [ infer S,...infer R] ? { [K in keyof [S,...R]] : [S,...R][K] } : never
type A = RebuildTuple<[1,2,3]>
// ^?
type A1 = RebuildTuple1<[1,2,3]>
// ^?
const abc=<T extends unknown[]>(v:T extends never ? T : RebuildTuple<T>)=>{}
const abc1=<T extends unknown[]>(v:T extends never ? T : RebuildTuple1<T>)=>{}
abc([1,2,3])
//^?
abc1([1,2,3])
//^?
but they are indeed the same thing
Top comments (0)