I've been wanting to start a new blog series for a while now. In this series, I'll be sharing some lesser-known TypeScript features that many web developers might not be familiar with. In this first post, I'll be talking about the "as const" keyword.
What does "as const" do?
You can declare a variable "as const" in TypeScript. This makes the value of the variable a constant or in other words it makes the variable read-only. Meaning you cannot change or update the value. This is different than just declaring a variable with const. You can't redeclare values of a const variable but you can mutate it. If you use "as const" you can't redeclare or mutate it.
Here is an example:
// without as const const config = { theme: { primaryColor: '#3498db', secondaryColor: '#2ecc71', }, api: { baseUrl: 'https://api.example.com', version: 'v1', }, features: { enableAnalytics: true, enableNotifications: false, }, }; // this is allowed config.theme.primaryColor = '#ff0000'; // so is this config.features.enableNotifications = true ;
In this example we have a web app config that consists of a theme, api and features objects. These values as you might guess are probably almost never going to change.
If a team member has changed a value in this config and others don't know it might cause unneeded debugging hours to fix a trivial problem. To keep them as read-only objects you can infer them "as const"
// with as const const config = { theme: { primaryColor: '#3498db', secondaryColor: '#2ecc71', }, api: { baseUrl: 'https://api.example.com', version: 'v1', }, features: { enableAnalytics: true, enableNotifications: false, }, } as const; // <-- notice the as const here // this will result in a TypeScript error config.theme.primaryColor = '#ff0000'; // this will throw an error as well config.features.enableNotifications = true;
This is pretty cool but "as const" provides us with another useful feature as well. TypeScript is mainly used for it's type checking and by using "as const" you can declare stricter types. What I mean by that is instead of an value being type string it can be type literal string value.
Here is another example:
// without as const const config = { theme: { primaryColor: '#3498db', // Type: string secondaryColor: '#2ecc71', // Type: string }, api: { baseUrl: 'https://api.example.com', // Type: string version: 'v1', // Type: string }, features: { enableAnalytics: true, // Type: boolean enableNotifications: false, // Type: boolean }, }; // when you hover on this you'll see type: string config.theme.primaryColor // when you hover on this you'll see type: boolean config.features.enableAnalytics
But if we use "as const" we can see their values when we hover over these variables. Since they are read-only their type does not matter, they cannot change.
// with as const const config = { theme: { primaryColor: '#3498db', // Type: '#3498db' secondaryColor: '#2ecc71', // Type: '#2ecc71' }, api: { baseUrl: 'https://api.example.com', // Type: 'https://api.example.com' version: 'v1', // Type: 'v1' }, features: { enableAnalytics: true, // Type: true enableNotifications: false, // Type: false }, } as const; // when you hover on this you'll see type: '#3498db' config.theme.primaryColor // when you hover on this you'll see type: true config.features.enableAnalytics
Lets do a quick recap
So by using "as const" we can turn our variables into read-only variables meaning their types are turned into their values so TypeScript throws an error when we try to change them. It also provides us with better intelliSense meaning we can just hover on a variable to see their constant value.
Thanks for tagging along!
Feel free to connect with me on my socials from my profile.
Cheers!
Top comments (1)
If you want complete safety from mutations, you may want to Object.freeze all the inner objects and then also the outer object. This will prevent unwanted changes to the values so you can move with reassurance that your type definition is more accurate.