DEV Community

Finally, an easy way to use TypeScript enums

Cubicle Buddha on July 15, 2019

One of the best things that TypeScript provides is a standard enum type that simply doesn't exist in JavaScript. Yes, yes... there are thousands of...
Collapse
 
samuraiseoul profile image
Sophie The Lionhart • Edited

Why use a library when a simple type definition would do fine for the most part?

enum FoodPreference {
    vegan = 'vegan',
    vegetarian = 'vegetarian',
    omnivore = 'omnivore'
}

const foodPreferenceQuestion : {[preference in FoodPreference] : string } = {
    [FoodPreference.vegan] : 'Do you like nuts?',
    [FoodPreference.vegetarian] : "You're really a pescatarian aren't you?",
    [FoodPreference.omnivore] : 'You are the most picky omnivore in the history of ever I bet'
};

function getFoodPreferenceQuestion(preference : FoodPreference) {
    return foodPreferenceQuestion[preference];
}
Collapse
 
mateiadrielrafael profile image
Matei Adriel • Edited

Ik im super late, but you can use

const foodPreferenceQuestion: Record<FoodPreference, string> = {
    [FoodPreference.vegan] : 'Do you like nuts?',
    [FoodPreference.vegetarian] : "You're really a pescatarian aren't you?",
    [FoodPreference.omnivore] : 'You are the most picky omnivore in the history of ever I bet'
};
Collapse
 
uselesspickles profile image
Jeff Lau

That's basically what ts-enum-util does for you behind the scenes automatically, but more. It infers the type of the value you are "visiting"/"mapping", including whether it can be possibly null or undefined, and forces you to handle null/undefined values as necessary. It also allows you to optionally provide a handler for "unexpected" values that occur at runtime, but were not part of the original compile-time enum definition. It uses unique symbols as keys for these special handlers to absolutely guarantee 0% chance of collision with legitimate enum values.

Then there's also the other side of ts-enum-util which gives you convenient access keys/values of the enum at runtime, mapping from key->value and value->key, custom type guards to verify/cast number/string values as enum values, etc.

Collapse
 
samuraiseoul profile image
Sophie The Lionhart

Oh cool! That's awesome! Thanks for commenting even if it's late! Knowledge is welcome any time! :D

Collapse
 
cubiclebuddha profile image
Cubicle Buddha • Edited

Update: You're right. That object approach also has exhaustiveness checking. I'm glad I learned something! I will say that the ts-enum-util library has many more features than what I mentioned.

Here's my original reply for posterity. Note: I was super duper wrong.


You lose the exhaustiveness checking. This code compiles and it shouldn't:

enum FoodPreference {
    vegan = 'vegan',
    vegetarian = 'vegetarian',
    omnivore = 'omnivore'
    somethingNew = 'this is the new thing that is not going to get caught'
}

const foodPreferenceQuestion : {[preference in FoodPreference] : string } = {
    [FoodPreference.vegan] : 'Do you like nuts?',
    [FoodPreference.vegetarian] : "You're really a pescatarian aren't you?",
    [FoodPreference.omnivore] : 'You are the most picky omnivore in the history of ever I bet'
};

function getFoodPreferenceQuestion(preference : FoodPreference) {
    return foodPreferenceQuestion[preference];
}

// Woops, I get undefined;
const iHopeThisIsDefined = getFoodPreference(FoodPreference.somethingNew);

If you use the library, the code will throw a compiler error saying that you forgot to handle the new case.

Collapse
 
cubiclebuddha profile image
Cubicle Buddha

I updated my comment reply because the object approach does work. Although the library does have some other really cool features like easy ways to iterate over the enum.

Thread Thread
 
samuraiseoul profile image
Sophie The Lionhart • Edited

That could be useful, though I haven't really needed enums in recent times so maybe there is something for that as well?

Either way, glad you learned something new! :D

To be fair, I had to look it up a bit as I've only used enums a handful of times on my TS projects so far so I was unfamiliar but I was pretty sure that this was an existing feature. Basically what I'm trying to say is that I too learned this. :P

Thread Thread
 
cubiclebuddha profile image
Cubicle Buddha

Yea I recently had to iterate over an enum for a React project and its basically a giant headache. So when you need to do it it’s nice to have a library to reduce the headache haha.