Stop blindly replacing `enum` with `as const`

Published: (March 13, 2026 at 03:18 AM EDT)
3 min read
Source: Dev.to

Source: Dev.to

Introduction

You’ve probably seen many posts suggesting that we should replace TypeScript enum with as const objects because of benefits like:

  • better tree‑shaking
  • smaller bundle size
  • less runtime code

That advice isn’t entirely wrong, but it is often oversimplified.
The real question isn’t “Should we stop using enums?” but rather: Do we understand what TypeScript generates behind the scenes, and what trade‑offs we are making?

Numeric enums and the generated code

For numeric enums, TypeScript emits extra runtime code.

enum Direction {
  Up,
  Down,
  Left,
  Right,
}

The above is transpiled to JavaScript roughly like this:

var Direction;
(function (Direction) {
  Direction[Direction["Up"] = 0] = "Up";
  Direction[Direction["Down"] = 1] = "Down";
  Direction[Direction["Left"] = 2] = "Left";
  Direction[Direction["Right"] = 3] = "Right";
})(Direction || (Direction = {}));

At first glance that looks odd. TypeScript creates an IIFE (Immediately Invoked Function Expression) and assigns Direction["Up"] = 0. That assignment returns 0, so TypeScript also sets Direction[0] = "Up".

At runtime we get an object like this:

{
  Up: 0,
  Down: 1,
  Left: 2,
  Right: 3,
  0: "Up",
  1: "Down",
  2: "Left",
  3: "Right"
}

This is called reverse mapping:

Direction.Up   // 0
Direction[0]  // "Up"

as const objects

Now compare that with a plain object marked as const:

const DirectionConst = {
  Up: "Up",
  Down: "Down",
  Left: "Left",
  Right: "Right",
} as const;

This is just a regular JavaScript object, so there’s no reverse mapping or extra runtime code. Because of that, many developers find as const useful for:

  • frontend apps
  • configuration objects
  • route names
  • statuses
  • action types
  • other JS‑first patterns

Enums aren’t “bad”

The issue isn’t that enums are bad; it’s that many people replace them blindly without considering the use case. Not all enums are the same:

  • Numeric enums generate reverse mapping.
  • String enums do not generate reverse mapping.
  • const enum has a different set of trade‑offs (it’s inlined at compile time).

as const is not a 1:1 replacement for every enum use case. Before swapping, ask yourself:

  • Do we need reverse mapping?
  • Do we need a runtime enum object?
  • Are we using numeric enums or string enums?
  • Is this app code, library code, or protocol/compiler‑style code?
  • Are we optimizing for explicitness, bundle size, or JavaScript simplicity?

Conclusion

as const is a great pattern, and enums are not automatically wrong. The “senior move” isn’t to follow slogans like “Stop using enums.” It’s to understand how TypeScript works under the hood and choose the right tool for the right use case.

0 views
Back to Blog

Related posts

Read more »