DEV Community

Cover image for Matt's Tidbits #94 - Writing safe enums in TypeScript
Matthew Groves
Matthew Groves

Posted on • Originally published at matthew-b-groves.Medium

Matt's Tidbits #94 - Writing safe enums in TypeScript

Last time I wrote about how to get started with React Native. This week, I have a quick tidbit about writing safe enums in TypeScript!

Many programming languages have support for enums, but they work slightly differently in TypeScript.

It’s really simple to define and use an enum — you can do so like this:

enum MyEnum {
  A,
  B,
  C,
}

function foo(enum: MyEnum) {}

foo(MyEnum.A);
Enter fullscreen mode Exit fullscreen mode

What really surprised me is that it’s also perfectly valid to do this:

foo(42);
Enter fullscreen mode Exit fullscreen mode

WHY?!!? To be honest, this really makes no sense to me at all. If I’ve gone through all the trouble of defining an enum (and specifying an enum as a parameter to a function), why can I specify any arbitrary number in place of this enum and have it still be valid code?

<5 minute meditation break/>

The good news is, there’s a way to guarantee that your enums cannot be used in this way!

As in many other programming languages, enums are typically represented as integers — the first enum value is equivalent to 0, the second is 1, etc. However, TypeScript has support for two other types of enums: string-based and heterogeneous enums.

Unfortunately, heterogeneous enums suffer from the same problem as numeric enums. But, string-based enums do not!

So, if you change your enum definition to look like this:

enum MyEnum {
  A = 'A',
  B = 'B',
  C = 'C',
}
Enter fullscreen mode Exit fullscreen mode

Now the only way to call our foo function is by passing one of the valid enum values — passing arbitrary numbers (or strings) will produce the following compile error:

Argument of type '42' is not assignable to parameter of type 'MyEnum'.
Enter fullscreen mode Exit fullscreen mode

There may be cases where you want to be able to specify arbitrary numeric values for enums, but I will be sticking to the string-based version!

For more information on enums in TypeScript, check out the official handbook: https://www.typescriptlang.org/docs/handbook/enums.html

If anyone knows why TypeScript enums were designed with this behavior, please let me know in the comments!

Interested in working with me in the awesome Digital Products team here at Accenture? We’re hiring!

Oldest comments (0)