TypeScript - Tuples
TypeScript - Tuples
Section titled “TypeScript - Tuples”Tuples are a special type in TypeScript that represent fixed-size arrays where the type of the element at each specific position (index) is known and fixed. Unlike regular arrays which usually contain elements of the same type and can grow or shrink, tuples define a precise structure for a small collection of related values.
Think of them as defining the types for each element in an array of a specific length.
Declaring Tuples
Section titled “Declaring Tuples”Tuple types are declared using square brackets [] with the types listed in order.
Syntax
Section titled “Syntax”let tupleName: [type1, type2, type3, ..., typeN];Example
Section titled “Example”// A tuple representing a key-value pair (string key, number value)let keyValue: [string, number];keyValue = ["userId", 12345]; // OK
// A tuple representing RGB color valueslet rgbColor: [number, number, number];rgbColor = [255, 0, 128]; // OK
// A mixed tuplelet personRecord: [string, number, boolean];personRecord = ["Alice", 30, true]; // OK
// Incorrect assignments (wrong type or order)// keyValue = [12345, "userId"]; // Error: Type 'number' is not assignable to type 'string'. Type 'string' is not assignable to type 'number'.// rgbColor = [255, 0]; // Error: Type '[number, number]' is not assignable to type '[number, number, number]'. Source has 2 element(s) but target requires 3.// personRecord = ["Bob", 40]; // Error: Type '[string, number]' is not assignable to type '[string, number, boolean]'.Accessing Tuple Elements
Section titled “Accessing Tuple Elements”Tuple elements are accessed using zero-based numerical indices, just like arrays. TypeScript provides type safety for each index.
let employee: [number, string, string] = [101, "John Doe", "Engineering"];
let employeeId: number = employee[0]; // Type is known to be numberlet employeeName: string = employee[1]; // Type is known to be stringlet department: string = employee[2]; // Type is known to be string// let manager: string = employee[3]; // Error: Tuple type '[number, string, string]' of length '3' has no element at index '3'.
console.log(`ID: ${employeeId}`);console.log(`Name: ${employeeName}`);console.log(`Department: ${department}`);
// Modifying elements (respects the type at that index)employee[2] = "Marketing";// employee[0] = "E101"; // Error: Type 'string' is not assignable to type 'number'.Tuple Operations and Mutability
Section titled “Tuple Operations and Mutability”While tuples define a fixed structure at compile time, standard JavaScript array methods like push, pop, etc., can technically still be called on tuples at runtime. However, this should generally be avoided as it breaks the intended fixed-size, fixed-type-per-index nature of the tuple and TypeScript might not always catch type errors resulting from such modifications beyond the defined length.
It’s best practice to treat tuples as fixed-length structures after creation.
let myTuple: [string, number] = ["Count", 10];
// Updating elements is allowed and type-checked:myTuple[1] = 20;console.log(myTuple); // Output: [ 'Count', 20 ]
// Using push can bypass compile-time length checks (Use with caution!):// myTuple.push(true); // Error in TS 4.0+: Argument type boolean not assignable to string | number// In older TS versions or with less strict checks, this might compile,// but `myTuple` no longer strictly matches the [string, number] shape.// console.log(myTuple);
// pop() also works, but again modifies the tuple's structure// let removed = myTuple.pop();// console.log(removed);// console.log(myTuple);For immutability, consider using readonly tuples.
Readonly Tuples
Section titled “Readonly Tuples”Make tuples immutable using the readonly keyword.
const readOnlyCoord: readonly [number, number] = [10, 5];
// readOnlyCoord[0] = 15; // Error: Index signature in type 'readonly [number, number]' only permits reading.// readOnlyCoord.push(20); // Error: Property 'push' does not exist on type 'readonly [number, number]'.Destructuring Tuples
Section titled “Destructuring Tuples”Easily unpack tuple elements into individual variables, similar to array destructuring.
const httpStatus: [number, string] = [200, "OK"];
const [statusCode, statusMessage] = httpStatus;
console.log(`Status Code: ${statusCode}`); // Output: Status Code: 200console.log(`Status Message: ${statusMessage}`); // Output: Status Message: OK
// Type checking applies during destructuring// const [code, message, description]: [number, string, string] = httpStatus; // Error: Tuple type '[number, string]' of length '2' has no element at index '2'.Optional Tuple Elements
Section titled “Optional Tuple Elements”You can mark elements as optional using ?. Optional elements must appear at the end.
let optionalTuple: [string, number, boolean?];
optionalTuple = ["User", 1, true]; // OKoptionalTuple = ["Admin", 2]; // OK (optional element omitted)
console.log(optionalTuple[0]); // stringconsole.log(optionalTuple[1]); // numberconsole.log(optionalTuple[2]); // boolean | undefinedRest Elements in Tuples
Section titled “Rest Elements in Tuples”A tuple can have a rest element (...Type[]) at the end to represent an arbitrary number of trailing elements of a specific type.
// Must have at least a string and number, followed by any number of booleanslet mixedRestTuple: [string, number, ...boolean[]];
mixedRestTuple = ["Data", 100]; // OKmixedRestTuple = ["Data", 100, true]; // OKmixedRestTuple = ["Data", 100, true, false, true]; // OK
console.log(mixedRestTuple[0]); // stringconsole.log(mixedRestTuple[1]); // numberconsole.log(mixedRestTuple.slice(2)); // boolean[]Tuples are useful when you need to return multiple values from a function or represent a small, fixed collection where the position of each element has a specific meaning and type.