Arrays and Tuples

This lesson will focus on ways to work with collections of data. Arrays hold multiple values of the same type, while tuples allow you to specify the exact type and order of elements.

Array types

In TypeScript, you can specify that a variable is an array in two ways:

Syntax 1: Type followed by brackets

let pizzaIngredients: string[] = ["dough", "sauce", "cheese", "pepperoni"];
let pizzaPrices: number[] = [10.99, 12.99, 14.99];
let isAvailable: boolean[] = [true, false, true];

Syntax 2: Array generic type

let pizzaIngredients: Array<string> = ["dough", "sauce", "cheese", "pepperoni"];
let pizzaPrices: Array<number> = [10.99, 12.99, 14.99];
let isAvailable: Array<boolean> = [true, false, true];

This version uses TypeScript's generic type syntax:

  • Array is a generic type (a type that can work with different types)
  • The angle brackets <string> specify the type parameter - what type of elements the array will contain
  • Array<string> means the Array contains strings
  • Array<number> means the Array contains numbers

Think of it like a container, Array is the container, and <string> tells TypeScript what type of items go inside the container.

Type-safe arrays

TypeScript ensures all elements in an array are of the same type:

let pizza: string[] = ["dough", "sauce", "cheese"];
pizza.push("pepperoni"); // works- this is a string
pizza.push(42); // Error: Argument of type 'number' is not assignable to parameter of type 'string'

Loading code...

let pizza: string[] = ["dough", "sauce", "cheese"];
pizza.push("pepperoni"); // works- this is a string
pizza.push(42); // Error: Argument of type 'number' is not assignable to parameter of type 'string'

Mixed type arrays

You can create arrays that contain multiple types using union types (we will cover union types in detail later):

let mixedData: (string | number)[] = ["pizza", 10.99, "pepperoni", 12.99];
let pizzaInfo: (string | number | boolean)[] = ["Margherita", 2, true, "large"];

// Each element can be any of the types in the union
mixedData.push("cheese"); // OK - string
mixedData.push(15.50);    // OK - number
mixedData.push(true);     // Error: Argument of type 'boolean' is not assignable to parameter of type 'string | number'

Loading code...

let mixedData: (string | number)[] = ["pizza", 10.99, "pepperoni", 12.99];
let pizzaInfo: (string | number | boolean)[] = ["Margherita", 2, true, "large"];

// Each element can be any of the types in the union
mixedData.push("cheese"); // OK - string
mixedData.push(15.50);    // OK - number
mixedData.push(true);     // Error: Argument of type 'boolean' is not assignable to parameter of type 'string | number'

The (string | number)[] syntax means "an array where each element can be either a string or a number". The parentheses are important - they group the union type before the array brackets.

Empty arrays

When creating an empty array, you still need to specify the type:

let pizzaIngredients: string[] = [];
let pizzaPrices: number[] = [];

// TypeScript knows what types can be added
pizzaIngredients.push("dough"); // Works
pizzaIngredients.push(42); // Argument of type 'number' is not assignable to parameter of type 'string'.

Loading code...

let pizzaIngredients: string[] = [];
let pizzaPrices: number[] = [];

// TypeScript knows what types can be added
pizzaIngredients.push("dough"); // Works
pizzaIngredients.push(42); // Argument of type 'number' is not assignable to parameter of type 'string'.

Multi-dimensional arrays

You can create arrays of arrays:

let pizzaOrders: string[][] = [
  ["dough", "sauce", "cheese"],
  ["dough", "sauce", "pepperoni"],
  ["dough", "sauce", "mushrooms"]
];

Loading code...

let pizzaOrders: string[][] = [
  ["dough", "sauce", "cheese"],
  ["dough", "sauce", "pepperoni"],
  ["dough", "sauce", "mushrooms"]
];

This string[][] syntax means an array of arrays of strings:

  • The first [] represents the outer array
  • The second [] represents each inner array
  • string is the type of each element in the inner arrays

Array type inference

TypeScript can infer array types from initial values (see the Type Inference lesson for more details):

let pizzaIngredients = ["dough", "sauce", "cheese"]; // inferred as: string
let pizzaPrices = [10.99, 12.99, 14.99]; // inferred as: number

console.log(typeof(pizzaIngredients[0]));
console.log(typeof(pizzaPrices[0]));

Loading code...

let pizzaIngredients = ["dough", "sauce", "cheese"]; // inferred as: string
let pizzaPrices = [10.99, 12.99, 14.99]; // inferred as: number

console.log(typeof(pizzaIngredients[0]));
console.log(typeof(pizzaPrices[0]));

Tuples

Tuples are arrays with a fixed number of elements, where each element can have a different type:

let pizzaOrder: [string, number] = ["Margherita", 2];

In this tuple:

  • First element must be a string (pizza name)
  • Second element must be a number (quantity)
  • Must have exactly two elements

Tuple examples

// Pizza size and price
let pizzaSize: [string, number] = ["large", 14.99];

// Order details: pizza name, quantity, and price
let orderDetails: [string, number, number] = ["Margherita", 2, 21.98];

// Mixed types: pizza name, isAvailable, quantity
let pizzaInfo: [string, boolean, number] = ["Hawaiian", true, 5];

Tuple type safety

TypeScript enforces the order and the types of tuple elements:

let pizzaOrder: [string, number] = ["Pepperoni", 2]; // correct
let pizzaOrder2: [string, number] = [2, "Pepperoni"]; // error
let pizzaOrder3: [string, number] = ["Pepperoni"]; // error

Loading code...

let pizzaOrder: [string, number] = ["Pepperoni", 2]; // correct
let pizzaOrder2: [string, number] = [2, "Pepperoni"]; // error
let pizzaOrder3: [string, number] = ["Pepperoni"]; // error

Accessing tuple elements

You access tuple elements like array elements, but TypeScript knows the exact type of each position:

let pizzaOrder: [string, number] = ["Margherita", 3];

console.log(typeof(pizzaOrder[0])); // string
console.log(typeof(pizzaOrder[1])); // number

let pizzaName: string = pizzaOrder[0]; // string
let quantity: number = pizzaOrder[1]; // number

Loading code...

let pizzaOrder: [string, number] = ["Margherita", 3];

console.log(typeof(pizzaOrder[0])); // string
console.log(typeof(pizzaOrder[1])); // number

let pizzaName: string = pizzaOrder[0]; // string
let quantity: number = pizzaOrder[1]; // number

Optional tuple elements

You can make tuple elements optional using ?:

let product: [string, boolean?] = ["Large blue shirt"]; // Second element is optional
let product2: [string, boolean?] = ["Large blue shirt", true]; // Can still provide it

Loading code...

let product: [string, boolean?] = ["Large blue shirt"]; // Second element is optional
let product2: [string, boolean?] = ["Large blue shirt", true]; // Can still provide it

Rest elements with tuples

You can use rest elements to create tuples with a variable number of elements:

let numbers: [string, ...number[]] = ["count", 1, 2, 3, 4];
console.log(numbers);

Loading code...

let numbers: [string, ...number[]] = ["count", 1, 2, 3, 4];
console.log(numbers);

This example requires a string for first element, then the rest of the values should be numbers.

Summary

Arrays and tuples are ideal for working with collections of data in TypeScript. In the next lesson, we will cover adding type annotations to objects.