TypeScript Type Challenge Length of Tuple Walkthrough

| 2 min read

The goal of the challenge is to implement a generic type called Length that takes an array and returns the length of that array.

The challenge: https://github.com/type-challenges/type-challenges/blob/main/questions/00018-easy-tuple-length/README.md

Watch the video

An example case

For example, given the following cases, our Length type should return the type shown in the comments:

 Length<typeof tesla> // 4
Length<typeof spaceX> // 5
Length<5> // @ts-expect-error
Length<'hello world'> // @ts-expect-error

Approach

Like in the Tuple To Object, we're interested in the type of a specific element of an array. We can use indexed access types to do this.

We know that in TypeScript, like JavaScript arrays are objects, and those objects have a length property signifying their length. We therefore know that the T["length"] should give us the length of an array.

  type Length<T> = T["length"]

The solution

The above works, but throws TypeScript errors, as TypeScript doesn't have a guarantee that the type T passed into length will be an array, it may therefore not have a length property.

To solve this we can constrain the type of T to be only arrays:

  type Length<T extends any[]> = T["length"]

This solves most of our issues but leaves us with two errors in our example cases above. The errors occur as when we call Length<typeof tesla> the typeof tesla is a readonly array. We can't assign a readonly array to a any[] type, we therefore need to further constrain T to only allow readonly arrays.

  type Length<T extends readonly any[]> = T["length"]

This readonly constraint makes sense, as if we pass in a mutable array to Length, the only type that we will be able to get back will be number, rather than the length of our array. This is because mutable arrays can be changed at runtime, so TypeScript cannot infer the length of it.