ZetCode

TypeScript Arrays

last modified October 15, 2026

An array is an ordered collection of values stored under one name. TypeScript arrays are JavaScript arrays with a type for their elements. The type is written as T[] or Array<T>, where T is the element type; both forms mean the same thing. The compiler checks that only elements of this type are added, and it knows the type of every element that is read.

Creating Arrays

Arrays are usually created with array literals in square brackets.

creating_arrays.ts
const numbers: number[] = [1, 2, 3, 4, 5];
const fruits: Array<string> = ["Apple", "Banana", "Cherry"];
const mixed: (string | number)[] = ["a", 1, "b", 2];
const inferred = [true, false, true];
const empty: string[] = [];

console.log(numbers);
console.log(fruits);
console.log(mixed, inferred, empty.length);

The numbers array uses the shorthand syntax and fruits the generic Array<string> syntax. An array may hold several types when its element type is a union; the parentheses in (string | number)[] are required. The type of inferred is boolean[], inferred from the values.

An empty array literal needs an annotation. Without it, TypeScript cannot know what the array will contain.

$ npx tsx creating_arrays.ts
[ 1, 2, 3, 4, 5 ]
[ 'Apple', 'Banana', 'Cherry' ]
[ 'a', 1, 'b', 2 ] [ true, false, true ] 0

Accessing Array Elements

Elements are read by their index. The first element has index 0.

accessing_elements.ts
const numbers: number[] = [10, 20, 30, 40, 50];

console.log(numbers[0], numbers[2]);
console.log(numbers.at(-1));
console.log(numbers.length);
console.log(numbers[10]);

The at method also accepts negative indexes, which count from the end. The length property returns the number of elements. Reading an index that does not exist returns undefined.

Note that the compiler types numbers[10] as number, not number | undefined. The noUncheckedIndexedAccess compiler option makes index access include undefined, which forces a check before the value is used.

$ npx tsx accessing_elements.ts
10 30
50
5
undefined

Modifying Array Elements

An element is changed by assigning a new value to its index. The value must have the element type.

modifying_elements.ts
const numbers: number[] = [1, 2, 3, 4, 5];

numbers[1] = 10;
numbers[numbers.length - 1] *= 2;

console.log(numbers);
// numbers[0] = "one";  // Error: Type 'string' is not assignable to type 'number'

The array is declared with const, but its elements can still be changed: const only prevents assigning a different array to the variable. The second assignment doubles the last element. The commented line would not compile.

$ npx tsx modifying_elements.ts
[ 1, 10, 3, 4, 10 ]

Adding and Removing Elements

Several methods add and remove elements at the ends of an array or in the middle.

array_methods.ts
const numbers: number[] = [1, 2, 3, 4, 5];

numbers.push(6);
console.log(numbers);

const last = numbers.pop();
console.log(last, numbers);

const first = numbers.shift();
console.log(first, numbers);

numbers.unshift(0);
console.log(numbers);

const removed = numbers.splice(1, 2, 99);
console.log(removed, numbers);

The push method adds elements to the end and pop removes the last one. shift removes the first element and unshift inserts at the beginning. The splice method removes two elements starting at index 1, inserts 99 in their place, and returns the removed elements.

The type of last and first is number | undefined, because the array might be empty. All these methods change the original array.

$ npx tsx array_methods.ts
[ 1, 2, 3, 4, 5, 6 ]
6 [ 1, 2, 3, 4, 5 ]
1 [ 2, 3, 4, 5 ]
[ 0, 2, 3, 4, 5 ]
[ 2, 3 ] [ 0, 99, 4, 5 ]

Searching Arrays

Arrays have methods to test for values and to find elements that match a condition.

searching_arrays.ts
type Product = { id: number; name: string; price: number };

const products: Product[] = [
    { id: 1, name: "Keyboard", price: 45 },
    { id: 2, name: "Mouse", price: 20 },
    { id: 3, name: "Monitor", price: 180 },
];

const ids = products.map(p => p.id);
console.log(ids.includes(2), ids.indexOf(3));

const cheap = products.find(p => p.price < 30);
console.log(cheap?.name);

const missing = products.find(p => p.price > 1000);
console.log(missing);

console.log(products.findIndex(p => p.name === "Monitor"));
console.log(products.some(p => p.price > 100), products.every(p => p.price > 10));

The includes method checks for a value and indexOf returns its position or -1. find returns the first element for which the callback returns true; its type is Product | undefined, so optional chaining is used to read the name. findIndex returns the index of that element. some tests whether at least one element matches and every whether all of them do.

$ npx tsx searching_arrays.ts
true 2
Mouse
undefined
2
true true

Transforming Arrays

The map, filter, and reduce methods create new values from an array without changing it.

transforming_arrays.ts
const prices: number[] = [12, 45, 7, 30, 99];

const withTax = prices.map(price => Math.round(price * 1.2));
const expensive = prices.filter(price => price > 20);
const total = prices.reduce((sum, price) => sum + price, 0);
const labels = prices.map((price, index) => `#${index + 1}: ${price} EUR`);

console.log(withTax);
console.log(expensive);
console.log(total);
console.log(labels);
console.log(prices);

The map method applies a function to every element and returns an array of the results; its element type can differ from the original, as in labels, which is a string[]. filter keeps only the elements for which the callback returns true. reduce combines all elements into one value; the second argument, 0, is the initial value of sum.

The last line shows that the original prices array is unchanged.

$ npx tsx transforming_arrays.ts
[ 14, 54, 8, 36, 119 ]
[ 45, 30, 99 ]
193
[ '#1: 12 EUR', '#2: 45 EUR', '#3: 7 EUR', '#4: 30 EUR', '#5: 99 EUR' ]
[ 12, 45, 7, 30, 99 ]

Sorting Arrays

The sort method orders the elements of an array. Its default behavior is a common trap with numbers.

sorting_arrays.ts
const numbers: number[] = [10, 1, 5, 100, 25];

console.log([...numbers].sort());
console.log([...numbers].sort((a, b) => a - b));
console.log(numbers.toSorted((a, b) => b - a));

const words = ["pear", "Apple", "banana"];
console.log(words.toSorted((a, b) => a.localeCompare(b)));

Without a compare function, sort converts elements to strings and compares them as text, so 100 comes before 25. A compare function that returns a negative number, zero, or a positive number sorts numbers correctly; b - a sorts them in descending order.

The sort method changes the array it is called on, which is why the first two lines sort a copy made with the spread operator. The newer toSorted method returns a sorted copy and leaves the original untouched. It is part of ES2023, so the compiler needs "target": "es2023" or a later target (or the matching lib setting) in tsconfig.json. Strings are best sorted with localeCompare.

$ npx tsx sorting_arrays.ts
[ 1, 10, 100, 25, 5 ]
[ 1, 5, 10, 25, 100 ]
[ 100, 25, 10, 5, 1 ]
[ 'Apple', 'banana', 'pear' ]

Iterating Over Arrays

Arrays can be traversed with the for...of loop, the forEach method, or a classic for loop.

iterating_arrays.ts
const fruits: string[] = ["Apple", "Banana", "Cherry"];

for (const fruit of fruits) {
    console.log(fruit);
}

fruits.forEach((fruit, index) => {
    console.log(`${index}: ${fruit}`);
});

for (const [index, fruit] of fruits.entries()) {
    console.log(`${index + 1}. ${fruit.toUpperCase()}`);
}

The for...of loop is the simplest way to visit every element. forEach also passes the index to its callback. The entries method yields [index, element] pairs, which the loop destructures; TypeScript infers index as number and fruit as string.

$ npx tsx iterating_arrays.ts
Apple
Banana
Cherry
0: Apple
1: Banana
2: Cherry
1. APPLE
2. BANANA
3. CHERRY

Readonly Arrays

A readonly array type, or ReadonlyArray<T>, does not allow any changes.

readonly_arrays.ts
function sum(values: readonly number[]): number {
    values.push(0);
    return values.reduce((acc, v) => acc + v, 0);
}

A function that takes a readonly array promises not to modify it, and the compiler enforces the promise: methods such as push, pop, and sort do not exist on the type, and index assignment is rejected. Non-modifying methods such as map, filter, and toSorted remain available.

$ npx tsc --noEmit
readonly_arrays.ts(2,12): error TS2339: Property 'push' does not exist on type 'readonly number[]'.

Multidimensional Arrays

An array of arrays represents a table or a grid. Its type is written with two pairs of brackets.

multidimensional_arrays.ts
const matrix: number[][] = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
];

console.log(matrix[1][2]);

for (const row of matrix) {
    console.log(row.join(" "));
}

const transposed = matrix[0].map((_, col) => matrix.map(row => row[col]));
console.log(transposed);

console.log(matrix.flat().reduce((sum, n) => sum + n, 0));

The expression matrix[1][2] selects the second row and then its third element. The loop prints each row as a line of text.

The transposition turns rows into columns: for each column index, it collects that element from every row. The flat method creates a one-dimensional number[] from the matrix, here used to add up all nine numbers.

$ npx tsx multidimensional_arrays.ts
6
1 2 3
4 5 6
7 8 9
[ [ 1, 4, 7 ], [ 2, 5, 8 ], [ 3, 6, 9 ] ]
45

Best Practices

Source

TypeScript Handbook: Arrays

This tutorial covered arrays in TypeScript. The element type written in the array type is checked on every access, every added element, and every callback of the array methods.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all TypeScript tutorials.