Typed Arrays
A tuple is a typed array with a fixed length and a fixed type for each position.
Tuples are useful because every element in the array is a known type of value.
To define a tuple, write the type of each element, in order, inside square brackets.
The first example has a number, a boolean and a string, in that order. The second example puts the values in the wrong order.
Note: Even though we still have a boolean, a string and a number, the order matters in a tuple, so the second assignment is an error.
Example
ourTuple must hold a number, then a boolean, then a string. The assignment matches, so there is no error.
ourTuple with the tuple type [number, boolean, string], then assign [5, false, 'Coding God was here']. Nothing is printed.
Output: TypeScript file and captured output
// define our tuple
let ourTuple: [number, boolean, string];
// initialize correctly
ourTuple = [5, false, 'Coding God was here'];
Example
The same values in the wrong order do not match the tuple type, so this assignment fails to compile.
ourTuple as [number, boolean, string], then assign [false, 'Coding God was mistaken', 5] — the same kinds of values in the wrong order — so the assignment fails to compile.
Output: TypeScript file and captured output
// define our tuple
let ourTuple: [number, boolean, string];
// initialized incorrectly which throws an error
ourTuple = [false, 'Coding God was mistaken', 5];
Readonly Tuple
A good practice is to make your tuple readonly.
Tuples only have strongly defined types for their initial positions. In the first example, you can push a new value onto the tuple and see it printed. The second example uses readonly to stop that.
To learn more about modifiers like readonly, see the TypeScript Classes chapter.
Note: If you have used React, you have most likely worked with tuples already.
useState returns a tuple of the value and a setter function.
const [firstName, setFirstName] = useState('Dylan') is a common example.
Because of the tuple's structure we know the first value is a certain type, in this case a string, and the second value is a function.
Example
Nothing stops push on a normal tuple, so a fourth value sneaks in and shows up in the printed array.
ourTuple as [number, boolean, string], assign [5, false, 'Coding God was here'], push the string 'Something new and wrong' (allowed, no type safety past index 2), then log the tuple to show the extra value.
Output: TypeScript file and captured output
// define our tuple
let ourTuple: [number, boolean, string];
// initialize correctly
ourTuple = [5, false, 'Coding God was here'];
// We have no type safety in our tuple for indexes 3+
ourTuple.push('Something new and wrong');
console.log(ourTuple);
Example
With readonly, push does not exist on the tuple type, so the call is a compile error.
readonly tuple cannot be extended.
Declare a constant ourReadonlyTuple typed readonly [number, boolean, string] with [5, true, 'The Real Coding God'], then call push('Coding God took a day off') — the compiler must report that push does not exist on the readonly tuple type.
Output: TypeScript file and captured output
// define our readonly tuple
const ourReadonlyTuple: readonly [number, boolean, string] = [5, true, 'The Real Coding God'];
// throws error as it is readonly.
ourReadonlyTuple.push('Coding God took a day off');
Named Tuples
Named tuples let you give each position a name, which explains what the value at that index means.
Note: Named tuples give more context about what each index value represents.
Named tuple syntax
The positions are labelled x and y, so it is clear that graph holds a coordinate pair.
const graph: [x: number, y: number] = [55.2, 41.3];
Destructuring Tuples
Since tuples are arrays, you can also destructure them — pull the values out into separate variables in one step.
Note: If destructuring is new to you, review the JavaScript destructuring chapter.
Destructuring a tuple
x receives 55.2 and y receives 41.3, each typed as number.
const graph: [number, number] = [55.2, 41.3];
const [x, y] = graph;