This Crazy Syntax Lets You Get An Array Element's Type
Learn how to extract the type of an array element in TypeScript using the powerful Array[number]
trick.
Let's take a quick look back at the Array
type we saw earlier.
Array<string>;
This type describes an array of strings. To make that happen, we're passing a type (string
) as an argument to another type (Array
).
There are lots of other types that can receive types, like Promise<string>
, Record<string, string>
, and others. In each of them, we use the angle brackets to pass a type to another type.
But we can also use that syntax to pass types to functions.
Set
A Set
is JavaScript feature that represents a collection of unique values.
To create a Set
, use the new
keyword and call Set
:
const formats = new Set ();
If we hover over the formats
variable, we can see that it is typed as Set<unknown>
.
That's because the Set
doesn't know what type it's supposed to be! We haven't passed it any values, so it defaults to an unknown
type.
One way to fix this would be to pass some values to Set
so it understands what type it's supposed to be:
const formats = new Set (["CD", "DVD"]);
But, we don't want to pass any values to it initially.
We can get around this by passing a type to Set
when we call it, using the angle brackets syntax:
const formats = new Set <string>();
Now, formats
understands that it's a set of strings, and adding anything other than a string will fail:
formats .add ("Digital");
formats .add (8 );Argument of type 'number' is not assignable to parameter of type 'string'.2345Argument of type 'number' is not assignable to parameter of type 'string'.
This is a really important thing to understand in TypeScript. You can pass types, as well as values, to functions.
Most functions in TypeScript can't receive types. A common example where you might want to pass a type is when calling document.getElementById
.
const audioElement = document .getElementById ("player");
We know that audioElement
is going to be a HTMLAudioElement
. This type comes from the DOM typings, which we'll talk about later.
So, it makes sense that we should be able to pass it to document.getElementById
:
const audioElement = document .getElementById <HTMLAudioElement >("player");Expected 0 type arguments, but got 1.2558Expected 0 type arguments, but got 1.
But unfortunately, we can't. We get an error saying that .getElementById
expects zero type arguments.
We can see whether a function can receive type arguments by hovering over it. Let's try hovering .getElementById
:
(method) Document.getElementById(elementId: string): HTMLElement | null
.getElementById
contains no angle brackets (<>
) in its hover. Let's contrasting it with a function that can receive type arguments, like document.querySelector
:
(method) ParentNode.querySelector<Element>(selectors: string): Element | null
.querySelector
has some angle brackets before the parentheses. It shows the default value inside them - in this case, Element
.
So, to fix our code above we could replace .getElementById
with .querySelector
.
const audioElement = document .querySelector <HTMLAudioElement >("#player");
And everything works.
So, to tell whether a function can receive a type argument, hover it and check whether it has any angle brackets.
Check out my free book for devs of all levels to learn advanced type manipulation and real-world application development patterns in TypeScript.
Share this Book Teaser with your friends
Learn how to extract the type of an array element in TypeScript using the powerful Array[number]
trick.
Learn how to publish a package to npm with a complete setup including, TypeScript, Prettier, Vitest, GitHub Actions, and versioning with Changesets.
Enums in TypeScript can be confusing, with differences between numeric and string enums causing unexpected behaviors.
Is TypeScript just a linter? No, but yes.
It's a massive ship day. We're launching a free TypeScript book, new course, giveaway, price cut, and sale.
Learn why the order you specify object properties in TypeScript matters and how it can affect type inference in your functions.