Enums

An enum is a named set of related constants — like Direction.North or LogLevel.Error — that gives meaningful names to a fixed group of numeric or string values.

Learn Enums in our free TypeScript course — an interactive lesson with runnable examples, a practice exercise and a quick reference.

Part of the free TypeScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

An enum is like the buttons on a vending machine . Each button has a friendly label ( Cola , Water , Juice ) but maps to an internal slot number the machine actually uses. You press the name ; the machine works with the number . A numeric enum even keeps a little lookup card going the other way, so it can tell you which label slot 2 belongs to.

1. Numeric Enums & Reverse Mapping

A numeric enum assigns each member a number. By default they auto-increment from 0 ( North = 0 , East = 1 , …), though you can set values explicitly ( OK = 200 ). The interesting twist is the reverse mapping : at runtime the generated object maps both name → number and number → name, so Direction[0] gives back "North" .

2. String Enums

A string enum gives every member an explicit string value: {'enum LogLevel '} . The big win is readability — when you log or serialise a string enum member you see "DEBUG" , not a mysterious 0 . The trade-off: string enums have no reverse mapping , so you can only go name → value.

3. Enum vs Union of Literals (and const enums)

Both an enum and a union of string literals describe a fixed set of allowed values. The difference is cost: a regular enum emits a runtime object, while a union of literals ( "admin" | "editor" | "viewer" ) adds zero runtime code. A const enum splits the difference — it's inlined at compile time so each use is replaced by its literal value and no object is generated.

🎯 Your Turn

Mirror a string enum as a plain object. Fill in the two blanks marked ___ , then run it.

No blanks this time — just a brief and a starting outline. Recreate the object a numeric enum compiles to (including reverse mapping), run it, and check your output against the example in the comments.

Practice quiz

By default, what value does the first member of 'enum Direction { North, East, South, West }' get?

  • 1
  • North
  • 0
  • undefined

Answer: 0. Numeric enums auto-number from 0, so North is 0, East is 1, and so on.

What does 'Direction[0]' return for that numeric enum at runtime?

  • "North"
  • 0
  • undefined
  • an error

Answer: "North". Numeric enums have a reverse mapping, so indexing by the number returns the member name string.

Why does a numeric enum's runtime object store each member twice?

  • For performance
  • To support const enums
  • It is a TypeScript bug
  • Because of the reverse mapping (name to number AND number to name)

Answer: Because of the reverse mapping (name to number AND number to name). The reverse mapping means the object holds both name to number and number to name entries.

What is 'LogLevel["INFO"]' for 'enum LogLevel { Debug = "DEBUG", Info = "INFO" }'?

  • "Info"
  • undefined
  • "INFO"
  • 1

Answer: undefined. String enums have NO reverse mapping, so looking up by the value returns undefined.

What is the main readability win of a string enum over a numeric one?

  • Logged or serialised members show a readable value like "DEBUG"
  • It is faster at runtime
  • It has a reverse mapping
  • It uses less memory

Answer: Logged or serialised members show a readable value like "DEBUG". String enum members print their explicit string value, far easier to debug than a bare number.

What does a 'const enum' emit at runtime?

  • A frozen object
  • A plain object with reverse mapping
  • No runtime object at all (values are inlined)
  • A string-keyed Map

Answer: No runtime object at all (values are inlined). A const enum is inlined at compile time; each use is replaced by its literal value and no object is generated.

Which alternative to an enum adds ZERO runtime code?

  • A const enum
  • A union of string literals
  • A numeric enum
  • A namespace

Answer: A union of string literals. A union of literals like "admin" | "editor" is purely type-level and emits no runtime object.

How do you give enum members explicit numeric values?

  • enum HttpStatus { OK: 200 }
  • enum HttpStatus { 200, 404 }
  • You cannot set them
  • enum HttpStatus { OK = 200, NotFound = 404 }

Answer: enum HttpStatus { OK = 200, NotFound = 404 }. Assign with '=' as in 'enum HttpStatus { OK = 200, NotFound = 404 }'.

What happens to later members if you insert a member in the middle of a numeric enum?

  • Nothing changes
  • Every later member's auto-number shifts up by one
  • The enum throws
  • Only the new member gets a number

Answer: Every later member's auto-number shifts up by one. Auto-numbering shifts all following members, which can break persisted numeric values.

A string enum member compared with a raw string like 'level === "ERROR"' may complain because:

  • Strings cannot be compared
  • Enums are runtime-only
  • Each string enum member is its own type; compare against LogLevel.Error instead
  • It needs a reverse mapping

Answer: Each string enum member is its own type; compare against LogLevel.Error instead. A string enum member has its own literal type, so compare against the enum member (LogLevel.Error).