Why do we have const enums in Typescript?
Tags: webdev, javascript, typescript, tutorial
Published: 2024-06-17 13:33:22

Typescript usually has two schools of thought—enums and unions—with strong supporters on both sides of the argument. In today's issue, I want to avoid that debate and focus solely on Enums, specifically a different, lesser-known version of enums: const enums.

Before we go any further, let’s briefly talk about what enums are: Enums allow developers to define a list of named constants representing distinct states within their application. For instance, if you wanted to have a switch button, the values can either be on or off, and an enum is perfect to represent this state, as shown below:

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27037c0d-c06e-438a-9894-09afdc299f83_2596x972.png)

And you can use the above enum, just like any type in Typescript.

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa492c25d-76d4-4406-971d-1f169d99127b_2596x1380.png)

To understand the difference between enums and const enums, we first need to understand their behavior after compilation before the behavior is very similar.

---

**If you want to learn Typescript with weekly lessons, please subscribe to my [newsletter](https://www.allthingstypescript.dev/).**

---

In the book [Effective Typescript by Don Vanderkom](https://effectivetypescript.com/) (a strongly recommended read), the author says that typescript has no impact on Javascript runtime. This is because Types are removed during transpilation, leaving you with good old Javascript. You can learn more about this relationship in this [issue](https://www.allthingstypescript.dev/p/typescript-and-javascript-two-sides), which we covered a few weeks ago.

Enums are one of the few features TypeScript has which is not a type-level extension of JavaScript—[Official TS Docs](https://www.typescriptlang.org/docs/handbook/enums.html).

Of course, this isn’t always the case, and Enums are one of those exceptions, with Enums getting converted into objects instead of being removed, as shown below:

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd196029c-9729-4c0e-8ace-00bd42c42e6b_3840x1356.png)

So, when we pass an enum, the object that is produced during the transpilation process is referenced, as shown below.

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F873effa0-d6be-4b07-9b2e-68feebd58837_4584x1684.png)

Another thing to note about enums is that the values of each element in an Enum are numbers - _incrementing from 0, from the top down, unless the first number is indicated_ - instead of the values we entered above, so in our case, `ON` would be `0` and `Off` would be `1`. Below is a case where the initial number is indicated.

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe576ab10-214d-4318-888b-34499462c1a1_3840x1356.png)

In this case, On is `100` and Off is `101`

This isn’t always the desired behavior, but it can be fixed by explicitly adding the value of each element in the enum, such as having the value be a string.

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccfd5ecd-90ca-4daa-beb8-8a400b2210d9_3840x1356.png)

String Enums

Or even an expression, as shown below:

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b2d4089-87e3-4dfc-a57c-f404e7cd08af_2596x1380.png)

Computed Enums

---

**If you like my content and want to support my work, please consider supporting me (**_**you can buy me a double latte, the juice that powers my creativity and determination ☕️**_**) through [Github Sponsors](https://github.com/sponsors/mainawycliffe/).**

[☕️ Consider buying me a cup of coffee](https://github.com/sponsors/mainawycliffe/)

---

### Const Enums

This isn’t always desired, and that's where const enums come in. They are just like regular enums, but they are prefixed by the const keyword before their declaration.

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa486d3c-7fe9-4894-bf1e-6a0ee11c37e0_2596x972.png)

The other important difference is that const enum values get inlined instead of producing an object, taking us back to zero impact on the JS runtime, as const enums do not generate objects after transpilation.

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff77637d1-4c90-4ff2-b540-6bcb14a05328_3840x2020.png)

Generally speaking, regular enums are valid solutions, but in those cases where you don’t want to pay the penalty of extra code generated by using regular enums, const enums are a very good solution, as they don’t generate any code for their support.

As you can see, no more `Switch` object is being created. Of course, just like with regular enums, we still have the same issue of enum element values being incremental numbers unless otherwise specified.

![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0717c12b-6555-4618-a803-7da73dea4c5d_3840x2020.png)

### Conclusion

In this issue, we examined the difference between enums and const enums. Unlike regular enums, const enums don’t generate the javascript object; the code is inlined. This means that you are not paying the penalty for extra code generation that you get when using regular enums.

While this is normally not a concern for most projects, in some cases, it can have a negative impact, leading to large JS code being produced and longer build / transpilation times. This can easily be solved by using const enums, which would be easier to refactor compared to alternative solutions such as unions.