Arrays and Tuples in TypeScript

Understand how to work with arrays and tuples in TypeScript. We'll cover declaring, initializing, and manipulating these data structures.


Tuples, Rest Parameters, and Spread Syntax in TypeScript (for Beginners)

Understanding Tuples

A tuple in TypeScript is a type that allows you to express an array with a fixed number of elements, where the type of each element is known. Think of it like a rigid array where you know exactly what each position holds.

 // Example of a Tuple
let myTuple: [string, number, boolean] = ["Hello", 42, true];

console.log(myTuple[0]); // Output: "Hello"
console.log(myTuple[1]); // Output: 42
console.log(myTuple[2]); // Output: true 

In the example above, myTuple is a tuple that *must* contain a string at the first position, a number at the second, and a boolean at the third. Trying to assign something else or access an index outside of 0-2 will result in a TypeScript error.

Using Tuples with Rest Parameters

Rest parameters allow a function to accept an indefinite number of arguments as an array. When used with tuples, this becomes very powerful, allowing us to ensure specific argument types and order for some initial arguments, while accepting a variable number of arguments of the same type afterward.

 function processTuple(name: string, age: number, ...hobbies: string[]): string {
    return `Name: ${name}, Age: ${age}, Hobbies: ${hobbies.join(", ")}`;
}

console.log(processTuple("Alice", 30, "Reading", "Gardening", "Hiking"));
// Output: Name: Alice, Age: 30, Hobbies: Reading, Gardening, Hiking

// Error: Argument of type 'number' is not assignable to parameter of type 'string'.
// console.log(processTuple("Bob", 25, 123)); 

In this example, processTuple requires a string (name) and a number (age) as the first two arguments. After that, it can accept any number of strings as the hobbies argument. The ...hobbies: string[] part is the rest parameter. The type of the rest parameter is always an array.

Using Tuples with Spread Syntax

Spread syntax (...) can be used to unpack the elements of a tuple into another tuple or array. This is useful for creating new tuples based on existing ones, or for passing tuple elements as arguments to a function.

 // Creating a new tuple from an existing one
let firstTuple: [number, string] = [1, "one"];
let secondTuple: [boolean, ...[number, string]] = [true, ...firstTuple];

console.log(secondTuple); // Output: [true, 1, "one"]

// Using a tuple as arguments to a function
function greet(name: string, age: number): string {
    return `Hello, ${name}! You are ${age} years old.`;
}

let personInfo: [string, number] = ["Charlie", 28];
console.log(greet(...personInfo)); // Output: Hello, Charlie! You are 28 years old. 

The first example demonstrates creating a new tuple secondTuple by taking a boolean value (true) and spreading the elements of firstTuple. This creates a new tuple where the first element is a boolean, followed by the elements from firstTuple. Notice that we have to tell typescript that the rest of the elements spread from the first tuple are of type [number, string]. Without this typescript may give the first element of the tuple a type of number | string. The second example shows how to use spread syntax to pass the elements of a tuple personInfo as arguments to the greet function. This is a convenient way to call a function with a fixed number of arguments when those arguments are already stored in a tuple.

Combining Rest Parameters and Spread Syntax with Tuples

You can combine rest parameters and spread syntax to perform operations on tuples effectively.

 function combineTuples(prefix: string, ...tuples: [string, number][]): string[] {
    const result: string[] = [];
    for (const tuple of tuples) {
        const [name, value] = tuple;
        result.push(\`${prefix}: Name - ${name}, Value - ${value}\`);
    }
    return result;
}

const data1: [string, number] = ["ItemA", 10];
const data2: [string, number] = ["ItemB", 20];

const combined = combineTuples("Report", data1, data2);
console.log(combined);
// Output:
// [
//   'Report: Name - ItemA, Value - 10',
//   'Report: Name - ItemB, Value - 20'
// ] 

In this scenario, the combineTuples function accepts a prefix string and a variable number of tuples, each of type [string, number]. It processes each tuple to create a formatted string and returns an array of those strings. The data1 and data2 tuples are passed using the rest parameter. This demonstrates how tuples and rest parameters can be used together to handle structured data effectively in functions.