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 is not entirely wrong, but it is often oversimplified.
The real question is not “Should we stop using enums?”
The better question is:
Do we actually understand what TypeScript generates behind the scenes, and what trade-offs we are making?
The key idea: reverse mapping
For numeric enums, TypeScript generates extra runtime code.
enum Direction {
Up,
Down,
Left,
Right,
}
This 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 weird.
But here is what is happening:
- TypeScript creates an IIFE (Immediately Invoked Function Expression).
- It assigns
Direction["Up"] = 0. - That assignment returns
0, so TypeScript also setsDirection[0] = "Up".
So 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.
That means:
Direction.Up // 0
Direction[0] // "Up"
Why some developers prefer as const
Now compare that with:
const DirectionConst = {
Up: "Up",
Down: "Down",
Left: "Left",
Right: "Right",
} as const;
This is just a plain JavaScript object.
No IIFE.
No reverse mapping.
No extra enum runtime emit.
That is why many developers say as const can be better for:
- frontend apps
- config objects
- route names
- statuses
- action types
- other JS-first patterns
But does that mean enum is bad?
Not at all.
The real issue is that many people blindly replace enums without understanding the use case.
Because not all enums are the same:
- numeric enums generate reverse mapping
- string enums do not generate reverse mapping
-
const enumhas a different trade-off again -
as constis not a 1:1 replacement for every enum use case
The important takeaway
We should not blindly replace enum with as const just because it is trending.
Instead, we should ask:
- 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 JS simplicity?
Final thought
as const is a great pattern.
But enum is not automatically wrong.
The real senior move is not to follow slogans like:
“Stop using enums.”
The real senior move is to understand how TypeScript works behind the scenes and choose the right tool for the right use case.
Top comments (0)