DEV Community

Bosco Domingo
Bosco Domingo

Posted on

TypeScript Enums are *more than ok*

As long as you use text-based ones.

In TypeScript, enums by default assign numbers as the values in the order the keys are defined. This means that changing existing enums can lead to unwanted changes:

enum Enum {
    key0, // 0
    key1 // 1
}

// Later commit, disaster strikes
enum Enum {
    key0, // 0
    key2, // 1 - this was taken over
    key1, // 2
    key3 // 3
}

// And again, at a later commit just mayhem
enum Enum {
    key2, // 0
    key1, // 1
    key3 // 2
}
Enter fullscreen mode Exit fullscreen mode

We definitely want to avoid that. That's why you should assign values to your enums' keys, the best option being text (numbers still do weird things, watch the videos below to understand more).

as const objects

The biggest opponent to enums is the controversial as const object. The implementation goes something like this:

const ENUM = {
    key0: "0",
    key1: "1"
} as const;

type EnumKeys = keyof typeof ENUM; // "key0" | "key1"
type EnumValues = typeof ENUM[EnumKeys]; // "0" | "1"

// Which allows for
function example(key: EnumKeys, value: EnumValues): void {
    // ...
}

// Both have intellisense
example("key0", ENUM.key0); // Just like regular enums
example("key1", "1"); // But values are accepted too
Enter fullscreen mode Exit fullscreen mode

But the thing is string-based enums can already do that:

enum Enum2 {
    key0 = "0",
    key1 = "1"
}

// Which allows for
type Enum2Keys = keyof typeof Enum2 // "key0" | "key1"
type Enum2Values = `${Enum2}` // "0" | "1"

function example(key: Enum2Keys, value: Enum2Values): void {
    //...
}

// Both have intellisense
example("key0", Enum2.key0);
example("key1", "1"); // Now values are accepted too
Enter fullscreen mode Exit fullscreen mode

No need for extra convoluted code that people unfamiliar with TypeScript won't even understand. A much simpler and nicer way to achieve the same goal, using vanilla TS and string interpolation.

And this article doesn't even cover computed values and other awesome features enums have. I genuinely think they are a great addition, and hope the TC39 proposal to implement them in base JS goes through. They are present in almost any modern language for a reason, folks.


Sources:

Top comments (0)