Learn TypeScript
Using generic rest elements with tuple types
Using generic rest elements with tuple types
In this lesson, we will learn how to use generic rest elements with tuple types.
Understanding rest element types
We briefly touched on rest elements when we learned about tuples earlier in the course.
As a reminder, a rest element type is a type for a collection of tuple elements. Consider the type below:
type Scores = [string, ...number[]];
The first element in this tuple type is a string, with subsequent elements being numbers.
Using generic rest element types
A rest element type can be from a generic parameter. Let's explore this by carrying out the following steps:
- Open the TypeScript playground by clicking the link below:
- Make sure the TypeScript version in the Playground is set to at least v4 and paste the code from below:
type NameAndThings<T extends unknown[]> = [string, ...T];
- Add labels to the elements in the tuple as follows:
type NameAndThings<T extends unknown[]> = [name: string, ...things: T];
The labels make the structure of the tuple a little more readable.
- Declare a variable to hold numeric scores for Bob using our
NameAndThings
type:
let bobScores: NameAndThings<number[]>;
- Assign the following value to
bobScores
:
bobScores = ["Bob", 4, 9, 3];
Does a type error occur on this assignment?
- Now assign another value to
bobScores
:
bobScores = ["Bob", 4, "9", 3];
Does a type error occur on this assignment?
- Declare a variable to hold grades scores for Bill using our
NameAndThings
type. The tuple should contain a string-based name in the first element and grades in subsequent elements. The grades can be'A'
,'B'
, or'C'
.
- Assign the following value to
billGrades
:
billGrades = ["Bill", "A", "A", "C"];
Does a type error occur on this assignment?
- Now assign another value to
billGrades
:
billGrades = ["Bill", "A", "D", "C"];
Does a type error occur on this assignment?
Using generic rest element types in functions
Function parameters can be thought of as a tuple. Let's explore this in the following steps:
- Paste the following code into the editor:
function logThings<T extends unknown[]>(name: string, ...things: T) { console.log(things);}
The first parameter in this function is a string.
The function also accepts a varying number of subsequent parameters that are collected into the things
rest element. things
is required to be a tuple of type T
.
- Call the
logThings
function and pass"Bob"
and three numbers as parameters.
Why don't we need to pass the generic parameter explicitly?
- Call the
logThings
function again as follows:
logThings("Bob", 4, "9", 3);
Does a type error occur on this function call?
- Revise the
logThings
call to the following:
logThings<number[]>("Bob", 4, "9", 3);
Does a type error occur now?
Summary
Function parameters can be thought of as a tuple. Typing function parameters as a tuple allow strongly-typed functions to be created that have varying parameters.
Next up we will learn how to use the spread operator on a generic parameter.