Arrays
A typed array promises that every element is the same kind of value. TypeScript checks what goes in, knows what comes out, and can even lock an array against changes with readonly.
Two ways to write an array type
let scores: number[] = [88, 92, 79]; let names: Array<string> = ["Ana", "Ben"]; scores.push(95); names.push(3);
error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
number[] and Array<number> mean exactly the same thing. The bracket form is shorter and more common; the Array<…> form is the generic syntax you'll meet properly in lesson 20. Pick one and stay consistent.
Inferred element types
When you initialise an array with values, TypeScript infers the element type, and every method that reads from it knows that type:
const prices = [4.5, 12, 7.25]; const total = prices.reduce((sum, p) => sum + p, 0); const labels = prices.map(p => `$${p.toFixed(2)}`); console.log(total); console.log(labels);
23.75 [ '$4.50', '$12.00', '$7.25' ]
prices is number[], so p inside each callback is a number, and labels comes out as string[] — no annotations needed.
An array literal containing mixed values gets a union element type. [1, "two"] is inferred as (string | number)[]: each element may be either, and you'll need to check which before using string- or number-specific methods.
Empty arrays need a type
An empty array gives inference nothing to go on, so annotate it:
const queue: string[] = []; queue.push("build"); queue.push("test"); console.log(queue.length, queue[0]);
2 build
Reading past the end
By default, TypeScript assumes an index you read actually exists:
const colors = ["red", "green"]; const third = colors[2]; console.log(third);
undefined
third is typed as string, but its value is undefined. The compiler option noUncheckedIndexedAccess (lesson 38) changes indexed reads to string | undefined, forcing you to handle the missing case. Many teams turn it on for exactly this reason.
Readonly arrays
Put readonly before an array type and every mutating method disappears from it:
const weekdays: readonly string[] = ["Mon", "Tue", "Wed", "Thu", "Fri"]; console.log(weekdays.includes("Sat")); weekdays.push("Sat");
error TS2339: Property 'push' does not exist on type 'readonly string[]'.
Non-mutating methods like map, filter, slice and includes still work, because they return new arrays. ReadonlyArray<string> is the long-hand spelling of the same type.
Readonly parameters are a great way to promise callers that a function won't modify their data:
function average(values: readonly number[]): number { let sum = 0; for (const v of values) sum += v; return values.length ? sum / values.length : 0; } const temps = [18, 21, 24]; console.log(average(temps));
21
A normal number[] can be passed where a readonly number[] is expected, but not the other way around.
Arrays of objects
Element types can be anything, including object shapes (more on those in lesson 08):
const cart: { name: string; qty: number }[] = [ { name: "pen", qty: 3 }, { name: "pad", qty: 1 }, ]; const itemCount = cart.reduce((n, line) => n + line.qty, 0); console.log(itemCount);
4
Try it yourself
readonly is a compile-time check only. At runtime, the array is a normal JavaScript array. If you need an array that's frozen even for untyped code, also call Object.freeze() on it.