Announcing: A Free Book, A New Course, A Huge Price Cut...
It's a massive ship day. We're launching a free TypeScript book, new course, giveaway, price cut, and sale.
How you declare your variables in TypeScript affects whether or not they can be changed.
let
When using the let
keyword, the variable is mutable and can be reassigned.
Consider this AlbumGenre
type: a union of literal values representing possible genres for an album:
type AlbumGenre = "rock" | "country" | "electronic";
Using let
, we can declare a variable albumGenre
and assign it the value "rock"
. Then we can attempt to pass albumGenre
to a function that expects an AlbumGenre
:
let albumGenre = "rock";
const handleGenre = (genre : AlbumGenre ) => {
// ...
};
handleGenre (albumGenre );Argument of type 'string' is not assignable to parameter of type 'AlbumGenre'.2345Argument of type 'string' is not assignable to parameter of type 'AlbumGenre'.
Because let
was used when declaring the variable, TypeScript understands that the value can later be changed. In this case, it infers albumGenre
as a string
rather than the specific literal type "rock"
. In our code, we could do this:
albumGenre = "country";
Therefore, it will infer a wider type in order to accommodate the variable being reassigned.
We can fix the error above by assigning a specific type to the let
:
let albumGenre : AlbumGenre = "rock";
const handleGenre = (genre : AlbumGenre ) => {
// ...
};
handleGenre (albumGenre ); // no more error
Now, albumGenre
can be reassigned, but only to a value that is a member of the AlbumGenre
union. So, it will no longer show an error when passed to handleGenre
.
But there's another interesting solution.
const
When using const
, the variable is immutable and cannot be reassigned. When we change the variable declaration to use const
, TypeScript will infer the type more narrowly:
const albumGenre = "rock";
const handleGenre = (genre : AlbumGenre ) => {
// ...
};
handleGenre (albumGenre ); // No error
There is no longer an error in the assignment, and hovering over albumGenre
inside of the albumDetails
object shows that TypeScript has inferred it as the literal type "rock"
.
If we try to change the value of albumGenre
after declaring it as const
, TypeScript will show an error:
albumGenre = "country";Cannot assign to 'albumGenre' because it is a constant.2588Cannot assign to 'albumGenre' because it is a constant.
TypeScript is mirroring JavaScript's treatment of const in order to prevent possible runtime errors. When you declare a variable with const
, TypeScript infers it as the literal type you specified.
So, TypeScript uses how JavaScript works to its advantage. This will often encourage you to use const
over let
when declaring variables, as it's a little stricter.
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
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.
Learn how to use corepack
to configure package managers in Node.js projects, ensuring you always use the correct one.
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.