Sostieni AppuntiFacili con una piccola donazione su PayPal
Dona con PayPalAn array is a collection of items stored in contiguous positions, all accessible by a numeric index starting at 0. In plain JavaScript an array can freely mix types, but TypeScript lets you declare what kind of values an array is allowed to hold, so the compiler can catch mistakes before the code ever runs.
let arr: number[] = [1, 2, 3];
arr.push(4); // ok
// arr.push("5"); // error: Argument of type 'string' is not assignable to parameter of type 'number'
The type number[] reads as “an array of numbers”. You can use the same idea with any type: string[], boolean[], Person[], and so on.
TypeScript also accepts an equivalent generic form, Array<T>:
let names: Array<string> = ["Anna", "Luca"];
string[] and Array<string> mean exactly the same thing. The bracket syntax is more common in everyday code; the generic form becomes handy when the element type itself is complex (for example a union type), because it avoids extra parentheses.
An array can contain other arrays. The type simply nests the same way the values do:
var arr2: string[][] = [["Hello", "World"], ["Hi"], []];
Here arr2 is “an array of arrays of strings”. Each inner array is independently a string[], and an empty array [] is perfectly valid too, since it’s still an array of zero strings.
TIP
Read nested array types from right to left: string[][] is (string[])[] — “an array whose elements are each a string[]”.
A tuple looks like an array at first glance, but it is a fixed-length array with a specific type defined for each position. Where number[] says “any number of numbers”, a tuple says “exactly these types, in exactly this order”.
const coord: [number, string] = [1, "2"];
console.log(coord[0]); // 1 (typed as number)
console.log(coord[1].length); // 1 (typed as string, so .length is valid)
The compiler knows that coord[0] is always a number and coord[1] is always a string — not “a number or a string”, but specifically that one at that specific position. That’s why coord[1].length compiles: TypeScript knows position 1 is a string, and strings have a .length property.
If you declared coord as (number | string)[], TypeScript would only know that each element is “a number or a string”, without remembering which one goes where or how many elements there are. A tuple encodes structure, an array encodes a homogeneous collection. Use a tuple whenever a fixed number of values with fixed, distinct meanings travel together — a coordinate pair, an RGB triplet, a [key, value] entry.
WARNING
Tuples are a compile-time concept only. At runtime a tuple is a plain JavaScript array, so nothing stops you from calling .push() on it and breaking the “fixed length” guarantee unless you also mark it readonly (see below).
Arrays and tuples compose naturally. An array of tuples is a common and very useful pattern:
const coords: [number, number[]][] = [
[1.1, [1, 2]],
[-1, [3, 4.4]]
];
console.log(coords[0]); // [1.1, [1, 2]]
Here each element of coords is a tuple [number, number[]]: a single number paired with an array of numbers. This kind of nesting is exactly how you would model, for example, a list of [id, relatedIds] pairs.
Sometimes you want to guarantee that a collection is never mutated after creation. TypeScript supports a readonly modifier for both arrays and tuples:
const readonlyNumbers: readonly number[] = [1, 2, 3];
// readonlyNumbers.push(4); // error: Property 'push' does not exist on type 'readonly number[]'
const readonlyCoord: readonly [number, string] = [1, "2"];
// readonlyCoord[0] = 5; // error: Cannot assign to '0' because it is a read-only property
readonly removes mutating methods (push, pop, splice, index assignment, …) from the type, so the compiler stops you from accidentally changing something that’s meant to stay fixed — like a tuple representing a constant coordinate.
Tuples can also model “at least these, maybe more” shapes using optional (?) and rest (...) elements, the same syntax used in function parameters.
// second element is optional
let pair: [number, string?] = [1];
pair = [1, "one"]; // also valid
// a required first element, followed by any number of strings
let entry: [number, ...string[]];
entry = [1];
entry = [1, "a", "b", "c"];
An optional tuple element (string?) can be omitted entirely; a rest element (...string[]) can be repeated zero or more times. Combining both, tuples become a flexible way to describe function-argument-like shapes with strong typing.
What does the type `number[]` describe?
What is the key difference between a tuple and a regular array?
Given `const coord: [number, string] = [1, "2"];`, why does `coord[1].length` compile?
Which declaration is equivalent to `let names: string[];`?
What happens if you `.push()` onto a `readonly number[]`?
What does `[number, ...string[]]` describe?
At runtime, what is a TypeScript tuple actually represented as?
Scenario: You are building a small utility that stores geographic waypoints for a hiking app.
Task:
Waypoint as [number, number, string] representing latitude, longitude, and a label.Waypoint values.describeWaypoint(w: Waypoint): string that returns a formatted string using all three values.readonly version of one waypoint and verify (by trying to mutate it) that the compiler rejects the change.Learning objective: practice defining and consuming tuple types, and understand the guarantees readonly adds on top of them.
Scenario: You need to model a small dataset of student grades where each student has a name and a variable-length list of numeric scores.
Task:
[string, ...number[]].string, number?, ...number[] is not valid TypeScript — figure out and explain why optional elements must come before rest elements in a tuple).Learning objective: understand rest and optional tuple elements, their ordering rules, and how they combine to model variable-length structured data.
Prenota una lezione