DEV Community

Acid Coder
Acid Coder

Posted on

Typescript Loop Tuple With Length > 1000

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> 
Enter fullscreen mode Exit fullscreen mode

TS will complains

Image description

playground

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] } 
Enter fullscreen mode Exit fullscreen mode

playground
no error
Image description

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]) //^? 
Enter fullscreen mode Exit fullscreen mode

playground

Image description

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]) //^? 
Enter fullscreen mode Exit fullscreen mode

playground

the hint doesn't look pretty
Image description

but they are indeed the same thing

Image description

Top comments (0)