DEV Community

Cover image for TypeScript Best Practices — Using Enums
Stephen Gbolagade
Stephen Gbolagade

Posted on

TypeScript Best Practices — Using Enums

TypeScript is not just about validation, It's also about structure and today, let's talk about using ENUMS to save your team unnecessary hours of debugging.

In enterprise software development, we often use Typescript to ensure our data is consistent.

But aside from using any to deceive ourselves (not the machine), we also ignore the importance of ENUMS.

Here is a scenario:

Your company is developing a food delivery software and you have 3 type of users who can sign up as demonstrated in the snippet below.

Someone in your team used Vendor, another person used vendor, you used VENDOR

That's a simple bug that can waste hours of productivity.

Solution:

Use ENUM to define the structure of your user Role. ENUM is readonly and very strict, it'll get your team members in order.

Code snippets

// Do ✅️
enum Role {
  Vendor = "VENDOR",
  Customer = "CUSTOMER",
  Rider = "RIDER"
}

const userRole: Role = Role.Admin;

// Don't ❌️
const userRole = "VENDOR"; // Very badd

// learn moteat www.stephengade.com

Enter fullscreen mode Exit fullscreen mode

Top comments (14)

Collapse
 
tomosterlund profile image
Tom Österlund

I like using enums too for objects.

TS-team however, recommends we use objects instead, like:

Object.freeze({
 Vendor: "VENDOR",
  Customer: "CUSTOMER",
  Rider: "RIDER"
})
Enter fullscreen mode Exit fullscreen mode

enums have some type-safety issues: dev.to/ivanzm123/dont-use-enums-in...

Collapse
 
stephengade profile image
Stephen Gbolagade

This is a good take

Collapse
 
mordechaim profile image
Mordechai Meisels • Edited

No, use string unions instead.

Enums introduce a runtime construct and typescript should only be a compile-time tool.

Unions gives you all the type safety and -- for libraries -- works for JavaScript (i.e. non typescript) projects flawlessly.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

I get what you mean, but what you say is wrong: It is a compile-time tool, or better stated, a transpilation tool since JS is not compiled by today's tools. Today's tools transpile, bundle and minify, but don't compile.

What you meant to say is that TS should not "write extra code", or at least this is what I think you meant. If I'm correct, that's also wrong: TypeScript, depending on the target version of ECMAScript, will generate code accordingly. By design, TS is meant to support as much as possible all the newest syntax ahead of time, and is ready to shim on the fly.

Finally, there is no absolute "best" enum. String unions are nice, but numeric enums are great:

  • A numeric enum only consume a fixed number of bytes regardless of its value, while a string consumes bytes depending on the string length.
  • A numeric enum can be used as a set of Boolean values when its values are single bits, and both read and write operations are O(1).
Collapse
 
sc7639 profile image
Scott Crossan

Came here to say this

Collapse
 
dmitryefimenko profile image
Dmitry A. Efimenko

Enums in typescript are not great. Most of the time when you're thinking about using enums, try using string literal instead:

type Role = 'VENDOR' | 'CUSTOMER' | `RIDER`;
Enter fullscreen mode Exit fullscreen mode

This provides same level of type safety, same intellisence, but less verbose and easier to use

Collapse
 
michael_mannseicher_836f6 profile image
Michael Mannseicher • Edited

I would do it so

const ROLES = <const>['VENDOR','CUSTOMER' ,'RIDER'];
type Role = typeof ROLES[number];
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ironblossom profile image
Ishtiaq Mahmood Amin

Enums are horrible, considering the alternatives that typescript provides

Collapse
 
theoephraim profile image
Theo Ephraim • Edited

Aside from the other issues mentioned, it's often very useful to use an object to store additional metadata that may be needed when using the options. You can use keyof typeof to extract the keys into a type (string union) to be used throughout your code.

For example:

const ANIMAL_DATA = Object.freeze({
  dog: { scientificName: 'Canis lupus familiaris' },
  cat: { scientificName: 'Felis catus' },
});

export type AnimalsEnum = keyof typeof ANIMAL_DATA; // 'dog' | 'cat'
Enter fullscreen mode Exit fullscreen mode
Collapse
 
juniourrau profile image
Ravin Rau • Edited

I used to use enum last time, but there were some issues that I faced.

  • increase in the size of the output
  • no proper type safety for string enums

Since then have been using plain object

const Role = {
    VENDOR: "Vendor",
    CUSTOMER: "Customer",
    RIDER: "Rider"
};

// Usage
console.log(Role. RIDER); // Output: Rider
Enter fullscreen mode Exit fullscreen mode
Collapse
 
guilherme_taffarelbergam profile image
Guilherme Taffarel Bergamin

Sometimes it's better to use Types for this kind of stuff because enums generate a lot of unnecessary transpired code (not a big issue if you don't have too many, tho) and because types will more easily resonate with people still using strings for this kind of stuff. It's still forcing everyone to use the correct string too.

Collapse
 
hugohub profile image
Karlis Melderis

If there would be easy fix for this in JS 🤔
Otherwise I tend to agree that enums are obsolete

typescriptlang.org/play/?#code/KYO...

Collapse
 
varma_sagi_82f557ba2d8a09 profile image
Varma Sagi • Edited

Enums is almost an useless feature in TS and you hardly wrote about it

Collapse
 
vrboop profile image
varun-r-boop

Enums are bad in ts they were not made for ts they are not even type safe the better alternative would be to use objects or union types