TypeScript course menu
TypeScript Arrays and Tuples: string[], Array<T>, readonly Arrays and Tuple Types
Learn to type arrays in TypeScript with string[] and Array<string>, arrays of objects and unions, readonly arrays, tuples for fixed-length arrays with known positions, optional and named tuple elements, and when to use an object instead.
On this page
Arrays are typed by the type of their items. Tuples are arrays with a fixed length where each position has its own type.
Array types#
There are two equivalent ways to write an array type:
const scores: number[] = [72, 95, 58];
const names: Array<string> = ["Asha", "Ravi"];
scores.push(88);
console.log(scores, names);[ 72, 95, 58, 88 ] [ 'Asha', 'Ravi' ]number[] is the more common style. Array<number> uses generic syntax, explained in Generics.
Every item must match the type:
const scores: number[] = [72, 95];
scores.push("100");error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.Array methods know the item type, so their results are typed too:
const prices = [120, 450, 80];
const labels = prices.map((p) => `₹${p}`); // string[]
const total = prices.reduce((sum, p) => sum + p, 0); // number
console.log(labels, total);[ '₹120', '₹450', '₹80' ] 650Arrays of objects and unions#
const students: { name: string; marks: number }[] = [
{ name: "Asha", marks: 92 },
{ name: "Ravi", marks: 78 },
];
const ids: (string | number)[] = [101, "A-7", 205];
console.log(students.filter((s) => s.marks > 80).map((s) => s.name));
console.log(ids.length);[ 'Asha' ]
3Note the parentheses in (string | number)[]: an array whose items are strings or numbers. Without them, string | number[] would mean "a string, or an array of numbers". Object types are usually given a name with an interface or type alias.
Reading items#
By default, TypeScript assumes an index you read exists, so scores[10] has the type number, even though at runtime it is undefined. The noUncheckedIndexedAccess compiler option makes indexed reads include undefined, forcing you to check (tsconfig.json). Methods like find and at already return T | undefined:
const scores = [72, 95, 58];
const firstHigh = scores.find((s) => s > 90); // number | undefined
console.log(firstHigh ?? "none");95readonly arrays#
A readonly array cannot be changed, which is useful for function parameters that should not modify their input:
function total(prices: readonly number[]): number {
prices.push(0);
return prices.reduce((a, b) => a + b, 0);
}error TS2339: Property 'push' does not exist on type 'readonly number[]'.Non-mutating methods such as map, filter, slice and toSorted still work. ReadonlyArray<number> is the same type written generically.
Tuples#
A tuple is an array with a fixed number of items, where each position has a known type:
const point: [number, number] = [12, 7];
const entry: [string, number] = ["maths", 92];
const [subject, mark] = entry;
console.log(point[0] + point[1], subject.toUpperCase(), mark + 1);19 MATHS 93Positions are checked:
const entry: [string, number] = [92, "maths"];error TS2322: Type 'number' is not assignable to type 'string'.Where tuples appear#
Functions that return several values often return tuples, which callers destructure. React's useState is a famous example. Object.entries returns [string, T][]:
function minMax(values: number[]): [number, number] {
return [Math.min(...values), Math.max(...values)];
}
const [lowest, highest] = minMax([7, 3, 9, 4]);
console.log(lowest, highest);
for (const [key, value] of Object.entries({ tea: 20, coffee: 35 })) {
console.log(key, value);
}3 9
tea 20
coffee 35Named, optional and rest elements#
type Range = [start: number, end: number]; // names document each position
type Rgb = [red: number, green: number, blue: number, alpha?: number];
type Command = [name: string, ...args: string[]]; // rest elements
const r: Range = [1, 10];
const colour: Rgb = [47, 95, 224];
const cmd: Command = ["git", "commit", "-m", "Initial commit"];
console.log(r, colour.length, cmd.slice(1).join(" "));[ 1, 10 ] 3 commit -m Initial commit(type creates a name for a type; see Type Aliases.)
Tuple or object?#
Tuples are compact but positions are easy to mix up. If there are more than two or three values, or their meaning is not obvious, use an object with named properties instead: { start: 1, end: 10 }.
Practice#
Practice exercise
Write a function splitName(full: string): [first: string, last: string] that splits a full name at the first space (the last name is the rest, or an empty string), and a function averageOf(values: readonly number[]): number. Test them.
Show solution
function splitName(full: string): [first: string, last: string] {
const space = full.indexOf(" ");
return space === -1 ? [full, ""] : [full.slice(0, space), full.slice(space + 1)];
}
function averageOf(values: readonly number[]): number {
return values.length === 0 ? 0 : values.reduce((a, b) => a + b, 0) / values.length;
}
const [first, last] = splitName("Asha Devi Rao");
console.log(first, "|", last);
console.log(splitName("Meera"));
console.log(averageOf([70, 85, 90]).toFixed(1));Asha | Devi Rao
[ 'Meera', '' ]
81.7Key takeaway#
Finished this lesson?