Array vs Tuple in TypeScript

TLDR: The type of an Array's length is number whereas a tuple's length is a finite static number.

So I was solving this typescript challenge isTuple the other day and I failed because I didn't know the key distinctions between a tuple and an array. So here I am sharing what I learned.

Arrays

Arrays are a list of values. These values can be of the same type or different types. It depends on the definition. One key feature of Arrays is that they have variable length. Values can be added/removed to it and the typescript won't complain about it.

// Array
let array: number[] = [1, 2, 3]
 
// Typescript won't complain if you update the array
array = [1, 2, 3, 4, 5] // Typescript - 🙂
array = [1] // // Typescript - 🙂

Note: Typescript will only complain if you add or remove items from the array which are different from the definition.

array = ['Hi, I am string', 2, 3] 
// Typescript - 😡, 
// Strings can't be added to the above array,
// as by the above defintion it only allows numbers

Tuples

Tuples are nothing but arrays with a fixed length.

// Tuples
let tuple: [number, number] = [1, 2]
 
tuple = [3, 4] // Typescript - 🙂
tuple = [1] // Typescript - 😡, Typescript expects two values

Length

The length property of tuple and array will give you different results and is the key differentiator between array and the tuple in typescript.

Array's length will give you the number type

type ArrayOfNumbers = numbers[]
 
type LengthArray = ArrayOfNumbers['length']
// number

where Tuple's length will give you a finite number based on the definition

type TupleOfTwoNum = [number, number]
 
type LengthTuple = TupleOfTwoNum['length']
// 2

Note: A finite number like 2 is a subset of the number type. But it does not work the other way around. The number is not a subset of 2

type Example1 = 2 extends number ? true : false // true
type Example2 = number extends 2 ? true : false // false

IsTuple Typescript Challenge

The above information on the length is the main thing you will need to solve the IsTuple challenge. Here is the solution as explained by the great Mike Poteat here:

type IsTuple<T> =
  [T] extends [never]
    ? false
    : T extends readonly unknown[]
      ? number extends T['length']
        ? false
        : true
      : false

Explaination:

  1. [T] extends [never] - checks if T is never
  2. T extends readonly unknown[] - checks if T is an array or tuple.
  3. number extends T['length'] - checks if T['length'] is number, if it's a number, it means is an array, otherwise a tuple

📚 Resources