How to Declare a Fixed-length Array in TypeScript

avatar
Borislav Hadzhiev

Last updated: Feb 27, 2024
5 min

banner

# Table of Contents

  1. Declare a Fixed-length Array in TypeScript
  2. Declare a Non-empty Array in TypeScript

# Declare a Fixed-length Array in TypeScript

Use a tuple to declare a fixed-length array in TypeScript.

Tuple types allow us to declare an array with a fixed number of elements whose types are known but can be different.

index.ts
// ✅ Declare a fixed-length array let arr: [string, number, number]; arr = ['coords', 10, 5]; // ⛔️ Error: Type '[string]' is not // assignable to type '[string, number, number]'. arr = ['a'];
The code for this article is available on GitHub

If you need to create an array of N empty elements, use the Array() constructor instead.

index.ts
const arr = new Array(4); console.log(arr); // 👉️ [, , ,] console.log(arr.length); // 👉️ 4

create array of n elements using array constructor

We declared a tuple with 3 elements with types of string, number and number.

index.ts
const arr: [string, number, number] = ['coords', 10, 5];

declare tuple in typescript

If you try to redeclare the arr variable to an array that doesn't contain 3 elements, you'll get an error.

If you add the correct number of elements to the array but mix up the types, you'd also get an error.

index.ts
let arr: [string, number, number]; arr = ['coords', 10, 5]; // ⛔️ Error: Type 'string' is not // assignable to type 'number'.ts(2322) arr = ['a', 10, 'b'];

The tuple type is used to declare an array with a fixed number of elements whose types are known but can be different.

# You can still push elements into a tuple

Having said that tuples are represented by an array, and you are still able to call the push() method to add an element to the tuple.

index.ts
const arr: [string, number, number] = ['coords', 10, 5]; // ✅ Ok arr.push('bobbyhadz.com'); // 👇️ [ 'coords', 10, 5, 'bobbyhadz.com' ] console.log(arr);

pushing elements into tuple

The code for this article is available on GitHub

# Declaring a read-only tuple

If you want to prevent this from happening, you can declare the tuple as readonly.

index.ts
const arr: readonly [string, number, number] = ['coords', 10, 5]; // ⛔️ Error: Property 'push' does not exist // on type 'readonly [string, number, number]'.ts(2339) arr.push('bobbyhadz.com');

But this also means that you aren't able to change the values of the tuple's elements.

index.ts
const arr: readonly [string, number, number] = ['coords', 10, 5]; // ⛔️ Cannot assign to '0' because // it is a read-only property.ts(2540) arr[0] = 'bobbyhadz.com'

Tuples are useful because when accessing a tuple at an existing index, TypeScript knows the type of the value.

index.ts
const arr: [string, number, number] = ['coords', 10, 5]; console.log(arr[0].toUpperCase()); // 👉️ "COORDS" console.log(arr[1].toFixed(2)); // 👉️ "10.00"

If you try to access the tuple at an index that doesn't exist, the type checker would throw an error.

index.ts
const arr: [string, number, number] = ['coords', 10, 5]; // ⛔️ Tuple type '[string, number, number]' of // length '3' has no element at index '3'.ts(2493) console.log(arr[3]);

# Using a tuple with optional values

If you need to declare an array that has a max length of X, use a tuple with optional values.

index.ts
// ✅ Array of Max length let arrOfMaxLength3: [string?, string?, string?] = []; arrOfMaxLength3 = ['a', 'b', 'c']; // ✅ OK arrOfMaxLength3 = ['a', 'b']; // ✅ OK arrOfMaxLength3 = ['a']; // ✅ OK // ⛔️ Error: Source has 4 element(s) but target allows only 3. arrOfMaxLength3 = ['a', 'b', 'c', 'd'];
The code for this article is available on GitHub

The question mark is used to mark the values in the tuple as optional. The tuple in the example can have a maximum of 3 elements (unless you use array methods to add more).

# Declaring an array with a minimum length of N

If you need to declare an array that has a minimum length of N, use the following approach.

index.ts
let arrOfMin2: [string, string, ...string[]] = ['a', 'b']; arrOfMin2 = ['c', 'd'] // ✅ OK // ⛔️ Error: Source has 1 element(s) // but target requires 2.ts(2322) arrOfMin2 = ['c']

The array can have a minimum of 2 elements of type string (unless you use an array method to remove an element).

# Declare a Non-empty Array in TypeScript

Use rest elements in a tuple type to declare a non-empty array.

index.ts
let arr: [number, ...number[]] = [1]; // ⛔️ Error arr = [];

Alternatively, you can use a type alias with a generic.

index.ts
type NonEmptyArr<T> = [T, ...T[]]; let arr: NonEmptyArr<string> = ['a']; arr = ['a', 'b']; // ✅ Works // ⛔️ Error arr = [];

We declared a non-empty array by using a tuple, that has a minimum length of 1.

The first example shows how to declare a non-empty array where the first element is a number and may contain zero or more additional elements.

The ...number[] syntax is called Rest elements in tuple types and indicates that the tuple is open-ended and may have zero or more additional elements of the specified type.

For example, [string, ...boolean[]] means a tuple with a string first element followed by any number of boolean elements.

The tuple can have more than 1 element, but if you try to re-declare it as an empty array, you'd get an error.

index.ts
let arr: [number, ...number[]] = [1]; // ⛔️ Error: Source has 0 element(s) but target requires 1.ts(2322) arr = [];

The tuple type is used to declare an array with a fixed number of elements whose types are known but can be different.

# Using a type alias to declare a non-empty array

You can also use a type alias to type a non-empty array.

index.ts
type NonEmptyArr<T> = [T, ...T[]]; let arr: NonEmptyArr<string> = ['bobby']; arr = ['hadz', 'com']; // ✅ Works // ⛔️ Error arr = [];
The code for this article is available on GitHub

The NonEmptyArr type is an array that contains at least 1 element of type T, but may have zero or more additional elements of type T.

Using this type alias in conditionals might be confusing.

index.ts
type NonEmptyArr<T> = [T, ...T[]]; const arr: string[] = ['a']; function getArr(arr: NonEmptyArr<string>) { return arr; } if (arr.length > 0) { // ⛔️ Error: Argument of type 'string[]' is not // assignable to parameter of type 'NonEmptyArr<string>'. getArr(arr); }

The easiest way to get around this is to use a type assertion.

index.ts
type NonEmptyArr<T> = [T, ...T[]]; const arr: string[] = ['a']; function getArr(arr: NonEmptyArr<string>) { return arr; } if (arr.length > 0) { // ✅ Works getArr(arr as NonEmptyArr<string>); }
The tuple type is used to express an array with a fixed number of elements whose types are known but can be different.

Having said that tuples are represented by an array, and you are still able to call the pop() method to remove elements from the tuple.

index.ts
const arr: [number, ...number[]] = [1]; arr.pop(); // ✅ OK console.log(arr); // 👉️ []

# Declaring the tuple as read-only

If you want to prevent this from happening, you can declare the tuple as readonly.

index.ts
const arr: readonly [number, ...number[]] = [1]; // ⛔️ Error: Property 'pop' does not // exist on type 'readonly [number, ...number[]]'.ts(2339) arr.pop();
The code for this article is available on GitHub

But this also means that you aren't able to change the values of the tuple's elements or add more elements.

I've also written an article on how to get the type of the array elements from an array type.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.