DEV Community

Cover image for Typescript: Enums

Typescript: Enums

Jatin Sharma on March 12, 2023

In this article, you'll learn about what enums are and how you can use them in your projects. Enums, short for Enumerated Types. This is going to...
Collapse
 
1canas profile image
Pedro Furlaneto

Nice article bro 🔥🔥

Could you give me an example of when I could use an enum instead of an object, please?

Keep going on the series dude!

Collapse
 
j471n profile image
Jatin Sharma

Objects are re-assignable but you can't assign values to enums types.

enum ExtraFries {
  No = "No",
  Yes = "YES",
}

let v1 = ExtraFries.No;
let v2 = ExtraFries.Yes;

// ❌ Type '"Yes"' is not assignable to type 'ExtraFries
v1 = "Yes";

// ❌ Cannot assign to 'No' because it is a read-only property.
ExtraFries.No = "Nooooo"

// ✅ This will work
v1 = ExtraFries.Yes
Enter fullscreen mode Exit fullscreen mode

But if we use object that it will allows us:

const obj = {
    no: "NO",
    yes:"YES"
}

let v3 = obj.no
v3 = "YES";

obj.no = "Nooooooooooooooo"
// It will allow everything
Enter fullscreen mode Exit fullscreen mode

You can check the playground:
typescriptlang.org/play?#code/PTAE...

Collapse
 
1canas profile image
Pedro Furlaneto

Thanks bro! 🤝

Collapse
 
karfau profile image
Christian Bewernitz • Edited

by appending as const to the value of obj you even get a read-only version of it, which can not be modified at runtime, and where obj.no and obj.yes have a narrowed type of the string literal value!

To even get a type for all the possible values, you can use the following snippet:

type EnumFromDict<T extends ReadonlyRecord<string, string>> = T[keyof T];
Enter fullscreen mode Exit fullscreen mode

of course it might help to have the same casing for both keys and values to simplify your searches.
Putting it all together:

export const YesNo = {
  Yes: 'Yes',
  No: 'No',
} as const;
export type YesNo = EnumFromDict<typeof YesNo>;
Enter fullscreen mode Exit fullscreen mode

(yes, you can export a type and a value with the same name from a module!)

This still allows you to use literal values everywhere and from what I know if as close as you can get to an enum.
If you need to reference the type of one of the keys from the const, you need to use typeof YesNo.Yes. (There are other options but they are longer.)

Hope it helps

Thread Thread
 
1canas profile image
Pedro Furlaneto

Thanks mate! It will helps for sure, I was searching for that way of typing

🤝🤝

Collapse
 
atinypixel profile image
Aziz Kaukawala

Helping a lot! 🫀
Please keep continuing the series mate!

Thank you! 🔥🔥

Collapse
 
j471n profile image
Jatin Sharma

Thanks mate. Definitely.

Collapse
 
briannbates profile image
Brian Bates

Really cool and helpful! Thanks!

Collapse
 
j471n profile image
Jatin Sharma

I am glad you find it useful 😊

Collapse
 
wraith profile image
Jake Lundberg

Great breakdown :) and thank you for sharing that the Heterogeneous enums are a bad idea! Keep up the good work!

Collapse
 
j471n profile image
Jatin Sharma

Thanks mate 😊

Collapse
 
swordheath profile image
Heather Parker

I loved this post series; it's incredible!

Collapse
 
j471n profile image
Jatin Sharma

Thanks Heather.

Collapse
 
eerk profile image
eerk

Since I discovered you can use strings as types I just use the following:

type Direction = "UP" | "LEFT" | "DOWN" | "RIGHT"
let direction : Direction = "boink"  // error :boink is not assignable to direction
let direction : Direction = "UP"      // allowed
Enter fullscreen mode Exit fullscreen mode

I find it actually less confusing than enums?

Collapse
 
dmitryefimenko profile image
Dmitry A. Efimenko

I wish this article didn't get this much positive feedback - or any at all for that matter.
I see comments like "Really cool and helpful! Thanks!". No, it's the opposite of helpful. It's spreading an anti-pattern. Nothing wrong with talking about what Enums are. But if you do that, you should also talk whether Enums should ever be used in TS. And the answer is - in most cases they should not.

TypeScript Enums are an awkward attempt to make Enums from C# or Java work in JS. They have weird edge-cases and should almost never be used. String literals will achieve the result with better ergonomics in most situations. This is the most important thing anybody need to know about JS Enums.

Don't believe me? Just do a quick google search and see smarter people talk about it.

Collapse
 
exotelis profile image
Sebastian Krah

I can just agree. Enums in TypeScript should be avoided. See also @karfau answer for a better approach.

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Great article..

Collapse
 
yoichitrigalot profile image
Yoïchi Trigalot

Such a great series of articles. Although I used type script in some of my projects, it helps me simplify, popularize, and understand better some subtleties.
Great job man! Appreciate 🔥