Learn TypeScript
Using some standard generic types
Using some standard generic types
In this lesson, we will learn the syntax for generic types before consuming some of the standard generic types in TypeScript.
Understanding the generic type syntax
Generic types allow us to create a specific type by enabling us to pass types into it as parameters. The parameters are passed inside angled brackets. If there are multiple parameters, they are separated by a comma.
const myVar = GenericType<SpecificType1, SpecificType2, ...>
This will make more sense when we use some of the standard generic types below.
Array<T>
One of the easiest generic types to understand is Array
. In fact, we have used this before when we first created a strongly-typed array. Let's explore this an exercise.
The code declares a scores
variable with a type annotation using the generic Array
type.
- Let's assign
scores
to an array of numbers:
scores = [70, 65, 75];
- Now assign
scores
to an array that contains a non-numeric element:
scores = [70, "65", 75];
The type checker picks up on the problem as we expect.
In the above example, we passed a primitive type into the generic type. However, we can pass any type into generic parameters. Let's explore this:
- Add the following code for a
Coordinate
type into the code editor:
type Coordinate = [number, number];
How can we use this Coordinate
type to create a coordinates
variable that is an array of Coordinate
type?
- Let's assign
coordinates
to a value:
coordinates = [ [30, 100], [100, 50],];
- Try giving a coordinate an extra dimension:
coordinates = [ [30, 100, 0], [100, 50],];
Does a type error occur when we add the extra dimension?
Let's move on to look at another useful generic type in the next section.
Promise<T>
We can use the Promise
generic type to specify the return type for asynchronous code. We specify the type of the item that is eventually returned in the generic parameter.
- Copy the code below and paste it into the code editor:
const promisedResponse: Promise<Response> = fetch("https://swapi.dev/api/");
The code uses the Promise
generic type to strongly-type what is returned from the fetch
function.
- Let's use the
then
method inpromisedResponse
to handle the response when the promise has been resolved. Type the code out rather than copying and pasting and notice the intellisense the editor provides.
promisedResponse.then((res) => console.log(res.ok));
What has TypeScript inferred the type of the res
parameter to be?
Record<K,V>
Generic types can have multiple parameters. Let's explore an example:
- Copy the code below and paste it into the editor:
type Result = { firstName: string; surname: string; score: number;};type ResultRecord = Record<string, Result>;
The Record
generic type allows a key-value object type to be created. We have used this to create a ResultRecord
type where the key is any string, and the value is of type Result
.
- Let's use our
ResultRecord
type to create some records:
const records: ResultRecord = { rodj: { firstName: "Rod", surname: "James", score: 70, }, janes: { firstName: "Jane", surname: "Smith", score: 95, }, fredp: { firstName: "Fred", surname: "Peters", score: 60, },};console.log(records);
In the example above, rodj
, janes
, and fredp
are the keys, and the values all have the Result
type.
How can we narrow the type of the record keys so that only 'rodj'
, 'janes'
or 'fredp'
are accepted? Make the change in our code.
- Let's add another record to our
records
object:
const records: ResultRecord = { ..., bobk: { firstName: "Bob", surname: "Keel", score: 65 }}
Is a type error raised?
Summary
Generic types allow us to create types that are reusable in many different situations. This is because we can create a specific type for our use case from a generic type by passing our types into it as parameters.
Excellent - we are starting to understand generic types!
In the next lesson, we will begin to create our own generic types.