Skip to content

Arrays & Tuples

JavaScript arrays are flexible—sometimes too flexible. TypeScript adds type safety and structure, ensuring that arrays contain what you expect and that tuples enforce fixed positions and lengths. This is where TypeScript starts to feel like a real modeling language rather than just a type checker.


Typed Arrays

In JavaScript, arrays can hold anything:

const values = [1, "two", false]

TypeScript lets you specify what an array should contain.

Basic typed arrays

const numbers: number[] = [1, 2, 3]
const names: string[] = ["Alice", "Bob"]

If you try to push the wrong type:

numbers.push("hello") // ❌ Error

Generic array syntax

Equivalent to number[]:

const numbers: Array<number> = [1, 2, 3]
// or
const numbers: number[] = [1, 2, 3]

Most developers prefer the shorter number[] syntax.


Union‑typed arrays

Arrays can hold multiple allowed types:

const values: (string | number)[] = ["hello", 42]

Array of objects

type User = { id: number; name: string }

const users: User[] = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" }
]

Typed arrays give you:

  • autocomplete for array elements
  • type‑safe .map, .filter, .reduce
  • compile‑time validation of mutations

Tuples: Fixed‑Length, Ordered Arrays

A tuple is an array with:

  • a fixed length
  • fixed types at each position

This is something JavaScript cannot express at all.

Basic tuple

const point: [number, number] = [10, 20]

If you swap values:

const point: [number, number] = ["x", 10] // ❌ Error

If you add extra values:

point.push(30) // ❌ Error in strict mode

Tuples with mixed types

const user: [string, number, boolean] = ["Alice", 30, true]

Named tuple elements (TS 4.0+)

This improves readability:

const user: [name: string, age: number] = ["Alice", 30]

Tuple Constraints

Tuples enforce:

1. Order

const result: [boolean, string] = [true, "OK"]

Switching order is invalid:

[ "OK", true ] // ❌ Error

2. Length

const rgb: [number, number, number] = [255, 128, 64]

Adding or removing values is not allowed.

3. Exact types per index

const response: [number, string] = [200, "Success"]

This is extremely useful for:

  • returning multiple values
  • parsing structured data
  • modeling fixed protocols
  • React hooks (const [state, setState] = useState(...))

Readonly Tuples

Readonly tuples prevent mutation.

const coords: readonly [number, number] = [10, 20]

coords[0] = 99     // ❌ Error
coords.push(30)    // ❌ Error

Readonly tuples are ideal for:

  • coordinates
  • configuration constants
  • return values that must not be modified

Readonly arrays vs readonly tuples

const arr: readonly number[] = [1, 2, 3]
const tup: readonly [number, number] = [1, 2]
  • readonly number[] → any length, but immutable
  • readonly [number, number] → fixed length and immutable

Putting It All Together

Here’s a realistic example combining typed arrays, tuples, and readonly constraints:

type User = {
  id: number
  name: string
}

const users: User[] = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" }
]

// A function returning a tuple
function findUser(id: number): [found: boolean, user: User | null] {
  const user = users.find(u => u.id === id)
  return [!!user, user ?? null]
}

const [found, user] = findUser(1)

// A readonly tuple for coordinates
const origin: readonly [number, number] = [0, 0]

This example demonstrates how TypeScript lets you model data structures with precision and safety.


Summary

In this lesson, you learned:

1. Typed arrays

  • enforce consistent element types
  • support unions and object types
  • improve .map, .filter, .reduce safety

2. Tuples

  • fixed length
  • fixed order
  • fixed types per index
  • ideal for structured return values

3. Readonly tuples

  • prevent mutation
  • perfect for constants and safe return values

These tools give you far more control over data structures than JavaScript alone, and they form the foundation for more advanced TypeScript features like discriminated unions and pattern matching.