How To Strongly Type process.env
Learn how to strongly type process.env in TypeScript by either augmenting global type or validating it at runtime with t3-env.
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
:
typescript
constformats = newSet ();
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:
typescript
constformats = newSet (["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:
typescript
constformats = newSet <string>();
Now, formats
understands that it's a set of strings, and adding anything other than a string will fail:
ts
formats .add ("Digital");Argument of type 'number' is not assignable to parameter of type 'string'.2345Argument of type 'number' is not assignable to parameter of type 'string'.formats .add (8 );
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
.
typescript
constaudioElement =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
:
typescript
constExpected 0 type arguments, but got 1.2558Expected 0 type arguments, but got 1.audioElement =document .getElementById <>("player"); HTMLAudioElement
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
.
typescript
constaudioElement =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.
This is a preview from my upcoming book.
If you’d like to receive updates about the book and all things TypeScript, subscribe below:
Share this Book Teaser with your friends
Learn how to strongly type process.env in TypeScript by either augmenting global type or validating it at runtime with t3-env.
Discover when it's appropriate to use TypeScript's any
type despite its risks. Learn about legitimate cases where any
is necessary.
Learn why TypeScript's types don't exist at runtime. Discover how TypeScript compiles down to JavaScript and how it differs from other strongly-typed languages.
Improve React TypeScript performance by replacing type & with interface extends. Boost IDE and tsc speed significantly.
In this book teaser, we discuss deriving vs decoupling your types: when building relationships between your types or segregating them makes sense.
Learn how TypeScript's new utility type, NoInfer, can improve inference behavior by controlling where types are inferred in generic functions.