TypeScript Tuples
A tuple is a special type in TypeScript that allows you to express an array with a known number of elements and types. Unlike regular arrays, the type of each element at each position in a tuple is fixed.
Declaring and Initializing Tuples
You can define a tuple by specifying a series of types in square brackets [].
// Declare a tuple type containing a string and a number
let person: [string, number];
// Initialize
person = ["John Doe", 30]; // OK
// Order must match
// person = [30, "John Doe"]; // Error: Type 'number' is not assignable to type 'string'.
// Count must match
// person = ["John Doe"]; // Error: Type '[string]' is not assignable to type '[string, number]'.Accessing Tuple Elements
You can access elements in a tuple using indexes, just like accessing array elements. TypeScript will provide the correct type hints based on the index.
console.log(person[0]); // Type is string
console.log(person[1]); // Type is number
// Call methods of the corresponding type
console.log(person[0].substring(0, 4)); // "John"
console.log(person[1].toFixed(2)); // "30.00"
// person[0] = 100; // Error: Type 'number' is not assignable to type 'string'.Destructuring Assignment with Tuples
You can use destructuring assignment to conveniently get all elements from a tuple.
let [fullName, age] = person;
console.log(fullName); // "John Doe"
console.log(age); // 30Optional Tuple Elements
Tuple elements can also be optional by adding ? after the type. Optional elements must be at the end of the tuple.
let car: [string, number, boolean?];
car = ["Toyota", 2022]; // OK
car = ["Honda", 2023, true]; // OKTuples vs Arrays Comparison
| Feature | Array | Tuple |
|---|---|---|
| Length | Variable, not fixed | Fixed, determined at definition |
| Type | All elements typically same type (string[]) | Each element can have different, predefined types ([string, number]) |
| Usage | Store lists of homogeneous data | Represent a fixed set of heterogeneous data, like key-value pairs, multiple function return values |
| Type Safety | Ensures all elements match array type | Ensures each position's element matches its specified type |
Out-of-Bounds Access to Tuples
In earlier versions of TypeScript, out-of-bounds operations on tuples (like pushing a new element) were allowed, but when accessing this out-of-bounds element, its type would be treated as a union type of all possible types in the tuple.
let myTuple: [string, number] = ["hello", 10];
// Before TypeScript 4.0, this was allowed
// myTuple.push(true);
// Accessing out-of-bounds element
// let value = myTuple[2]; // value's type is string | numberHowever, as TypeScript has evolved, type checking for tuples has become increasingly strict. Now, it's generally not recommended to perform operations like push that change the tuple's length, as this violates the "fixed length" principle of tuples.
Common Use Cases
Multiple return values from functions: When a function needs to return multiple values of different types, tuples are a good choice.
typescriptfunction fetchUser(): [string, number] { // ... logic return ["admin", 1]; }Representing key-value pairs: When handling data like what
Object.entries()returns.typescriptconst entries: [string, any][] = Object.entries({ name: "Alice", age: 25 }); // entries is an array of tuples: [["name", "Alice"], ["age", 25]]