Enums
An enum is a named set of constants. Unlike most of TypeScript, an enum is
not erased at compile time: it becomes a real JavaScript object. For this
reason modern code often uses a union of string literals or an as const
object instead.
Applies to: TypeScript 7.0.
Details
Kinds of Enums
- Numeric. Members are numbered from
0or from the given initializer. They have a reverse mapping from value to name. Any expression of typenumbercan be assigned to a numeric enum, so they are less type-safe. Only a literal that is not a member value (99) is rejected. - String. Every member needs an initializer. There is no reverse mapping. A
plain string is not assignable: you have to write
Status.Active. const enum. Has no object at runtime: the compiler inlines the values where they are used. Tools that compile one file at a time (Babel, SWC,isolatedModules) can't inline aconst enumdeclared in another file.
Why Enums Are Avoided
- They generate runtime code, while almost all the rest of TypeScript is only types.
- They can't be removed by "type stripping", which is how Node.js runs
TypeScript files directly. With
erasableSyntaxOnly(TypeScript 5.8) enabled an enum is a compile error. - A union of literals gives the same checks and autocompletion with no runtime code.
Alternatives
- A union type, when only the type is needed:
type Status = 'active' | 'blocked'. - An
as constobject, when the values are also needed at runtime, for example to iterate over them.
Example
enum Direction {
Up = 1,
Down,
Left,
}
console.log(Direction.Down); // 2
console.log(Direction[2]); // 'Down' (reverse mapping)
enum Status {
Active = 'ACTIVE',
Blocked = 'BLOCKED',
}
const current: Status = Status.Active;
const other: Status = 'ACTIVE';
// Error: Type '"ACTIVE"' is not assignable to type 'Status'.
The same without an enum:
const Role = {
Admin: 'admin',
User: 'user',
} as const;
type Role = (typeof Role)[keyof typeof Role]; // 'admin' | 'user'
const role: Role = 'admin';
console.log(Object.values(Role)); // ['admin', 'user']
Follow-up Questions
- What does an enum compile to? An object filled inside an immediately invoked
function; a numeric enum gets both
name → valueandvalue → namekeys. - When is an enum still a reasonable choice? In a codebase that already uses them, or when the values come from a backend that describes them as an enum.
- What is the difference between
enumandconst enum? Aconst enumleaves no object at runtime and can't be iterated.
Common Mistakes
- "Enums exist only at compile time." Only
const enumdoes. - "String enums have a reverse mapping." Only numeric ones.
- Iterating over a numeric enum with
Object.keys()and getting both names and values. - A string enum for values that arrive from an API:
'ACTIVE'is not assignable toStatus, so every response needs a cast. A union of literals accepts the string as is.