Learn TypeScript

Spreading generic tuple parameters

Spreading generic tuple parameters

In this lesson, we will learn how to use the spread syntax on generic tuple parameters and where this is beneficial.

An example function that uses the spread operator

We are going to start this lesson by exploring a function that uses the spread operator and discover a problem with the typing.

  • Open the TypeScript playground by clicking the link below:
Open TypeScript Playground
  • Make sure the TypeScript version in the Playground is set to at least v4 and paste the code from below:
function merge(names: string[], scores: number[]) {
return [...names, ...scores];
}
  • Add code to call this function as follows:
let scores = merge(["Bill", "Jane"], [8, 9]);
🤔

What is the inferred type of scores?

A more strongly-typed return type would be [string, string, number, number] or better still ["Bill", "Jane", 8, 9].

Spreading generic tuple parameters to narrow the return type

The spread syntax can be used on a generic tuple type using three dots (...). We are going to use this feature to narrow the return type of merge.

  • Revise the merge function signature as follows:
function merge<Names extends string[], Scores extends number[]>(
names: Names,
scores: Scores
) {
return [...names, ...scores];
}

We have added a generic parameter type called Names that is an array of strings, and a generic parameter type called Scores that is an array of numbers. These types are used in the type annotations for the name and scores function parameters.

🤔

What is the inferred type of scores now?

So, this hasn't narrowed the type as required.

  • Revise the merge function signature as follows:
function merge<Names extends string[], Scores extends number[]>(
names: [...Names],
scores: [...Scores]
) {
return [...names, ...scores];
}

We have spread the generic type parameters in the function parameter type annotations.

🤔

What is the inferred type of scores now?

A bit better, but still not as required.

  • Let's help TypeScript by adding a return type annotation to the function:
function merge<Names extends string[], Scores extends number[]>(
names: [...Names],
scores: [...Scores]
): [...Names, ...Scores] {
return [...names, ...scores];
}
🤔

What is the inferred type of scores now?

Great, we have finally narrowed the return type right down!

Summary

If we are using TypeScript version 4 or beyond, we can spread tuple generic parameter types. This is useful to help TypeScript better infer types on expressions that involve tuples.

Next up is a quiz to test what we have learned about generic types.

© 2020 Carl Rippon
Privacy Policy
This site uses cookies. Click here to find out more