rid
rid

Reputation: 63542

Tuple with number of components based on argument

Can I create a type that takes an argument N extending number and a type T, and returns a tuple with N components, each of type T?

Example:

type A<N extends number, T> = [?];

type E1 = A<2, number>;  // [number, number]
type E2 = A<3, boolean>; // [boolean, boolean, boolean]

Upvotes: 1

Views: 47

Answers (1)

jcalz
jcalz

Reputation: 329228

You could use a recursive conditional type with variadic tuple types to implement this; for example:

type TupleLen<N extends number, T, A extends any[] = []> =
  N extends A['length'] ? A : TupleLen<N, T, [T, ...A]>;

type E1 = TupleLen<2, number>;  // [number, number]
type E2 = TupleLen<3, boolean>; // [boolean, boolean, boolean]

Of course, the compiler doesn't really allow you to do arbitrary math with numeric literal types and the above type function is therefore fragile. If the N type parameter is specified with something you don't get as a length by recursively prepending to fixed-length tuples, you'll see some unfortunate behavior:

// don't write these unless you like to eat up your CPU
type Oops = TupleLen<-1, number>; // 🔥💻🔥 
// error: Type instantiation is excessively deep and possibly infinite.
type Oops2 = TupleLen<0.5, number>; // 🔥💻🔥 
// error: Type instantiation is excessively deep and possibly infinite.

One could try to harden TupleLen against such improper usages, at the expense of complexity. I won't go into that here, since it's probably out of scope. Anyway, that means you should be careful.

Playground link to code

Upvotes: 1

Related Questions