Start learning free

LESSON 264 OF 675 · TUPLES, SORTING & BUILT-INS

Tuples in TypeScript: Typed Pairs and Destructuring

Lesson Read the full explanation

TL ; DR:

A tuple type like [string, number] describes a pair, like a movie's title and year. Destructuring unpacks it into variables in one line.


const movie: [string, number] = ["Frozen", 2013];   // a tuple

console.log(movie[0]);                              // Frozen

const [title, year] = movie;                        // destructuring

console.log(title + " " + year);                    // Frozen 2013

function firstAndLast(word: string): [string, string] {
    return [word[0], word[word.length - 1]];
}

const [first, last] = firstAndLast("code");

console.log(first + last);                          // ce


Full lesson:

Some values belong together. A movie has a title and a year. A point has an x and a y. TypeScript keeps a pair like that in an array with a tuple type.

  • [string, number] is a tuple type. It has exactly two values, a string and then a number.
  • movie[0] is the first value, "Frozen". movie[1] is the second, 2013.
  • The type checks the values. ["Frozen", "2013"] is an error, and so is ["Frozen", 2013, 2014].

A plain (string | number)[] would allow any length and any order. The tuple type is stricter.

Destructuring gives each value its own name. Write the names in square brackets, in the same order as the values. After const [title, year] = movie;, title holds "Frozen" and year holds 2013. Their types come from the tuple type.

A function can return a tuple. Its return type is the tuple type, and return [a, b]; builds it.

Watch the count. A third name in const [a, b, c] = movie; is an error, because the tuple has only two values.


Your task

Rex the dog went for a long walk. pet holds his name and his age.

First, make splitTime return its tuple: the whole hours and the minutes left.

Then destructure pet into name and age.

Last, call splitTime(135). Destructure its result into hours and mins.

The code already prints the three lines.

Expected output:

Rex
Rex is 4
Rex walked 2 h 15 min
STEP 1 OF 3
    Ctrl + Enter to check

    TYPESCRIPT · TUPLES, SORTING & BUILT-INS

    Tuples in TypeScript, explained

    What a tuple is

    Some values belong together: a pet's name and age, a point's x and y. TypeScript keeps such a group in an array and describes it with a tuple type. The type [string, number] says: exactly two values, a string first and a number second.

    const pet: [string, number] = ["Rex", 4];
    console.log(pet[0]);   // Rex
    console.log(pet[1]);   // 4
    

    A plain (string | number)[] would accept any length and any order. The tuple type is stricter, and the compiler uses the position to know each value's type: pet[0] is a string, pet[1] is a number.

    Destructuring

    Writing pet[0] and pet[1] everywhere makes code hard to read. Destructuring gives each value its own name. Put the names in square brackets, in the same order as the values:

    const [name, age] = pet;
    console.log(name + " is " + age);
    
    Rex is 4
    

    Here name holds "Rex" and age holds 4, and their types come from the tuple type.

    Returning two values from a function

    A function can return only one value, but that value can be a tuple. The return type is the tuple type, and return [a, b]; builds it. The caller destructures the result straight away. This is the lesson's helper:

    function splitTime(minutes: number): [number, number] {
        return [Math.floor(minutes / 60), minutes % 60];
    }
    
    const [hours, mins] = splitTime(135);
    console.log(hours + " h " + mins + " min");
    
    2 h 15 min
    

    Division in TypeScript gives a decimal (135 / 60 is 2.25), so Math.floor keeps the whole hours. The operator % gives what is left over: 135 minutes leave 15.

    Destructuring in other places

    Destructuring works wherever you declare variables from an array. A for...of loop over an array of tuples can unpack each pair as it goes:

    const pets: [string, number][] = [["Rex", 4], ["Bella", 7]];
    for (const [name, age] of pets) {
        console.log(name + " is " + age);
    }
    

    Reading it aloud helps: "for each pair, call the first value name and the second age". The type [string, number][] is an array of such pairs.

    Traps

    • Types are only checked by the compiler. Writing ["Rex", "four"] for a [string, number] is reported as an error (a string is not assignable to a number), and so is ["Rex", 4, 5]. But tsc still writes the JavaScript, and at run time a tuple is an ordinary array.
    • A name too many. const [a, b, c] = pet; is reported as an error because the tuple has no element at index 2. If the code runs anyway, c is undefined.
    • Order matters. const [age, name] = pet; compiles, since names are just labels, but then age holds "Rex". The compiler gives the first name the first type, so the names have to match the order of the tuple.
    • Tuples are arrays underneath. Calling push on a [string, number] is allowed by the compiler, and the array then has three items. Treat a tuple as a fixed pair.

    The exercise

    The lesson has three steps, and the code already prints the three lines. First make splitTime return its tuple, as above. Then destructure pet into name and age. Last, call splitTime(135) and destructure the result into hours and mins. The finished program:

    function splitTime(minutes: number): [number, number] {
        return [Math.floor(minutes / 60), minutes % 60];
    }
    
    const pet: [string, number] = ["Rex", 4];
    console.log(pet[0]);
    
    const [name, age] = pet;
    console.log(name + " is " + age);
    
    const [hours, mins] = splitTime(135);
    console.log(name + " walked " + hours + " h " + mins + " min");
    

    It prints:

    Rex
    Rex is 4
    Rex walked 2 h 15 min
    

    Key takeaways

    • A tuple type such as [string, number] fixes the length and the type at each position.
    • Destructuring with const [a, b] = tuple; names the values in order.
    • A function that must give back two values returns a tuple.
    • Tuple types are checked by the compiler and erased at run time.
    Keep going with TypeScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free