enum Status { Idle = "idle", Loading = "loading" }
type StatusUnion = "idle" | "loading";
const STATUS = { Idle: "idle", Loading: "loading" } as const;
type StatusFromObject = (typeof STATUS)[keyof typeof STATUS];
Many frontend teams, me included, prefer string literal unions. They cost nothing at runtime and accept plain strings. If you also need the values at runtime, use an as const object with a derived union. The caveat with const enum is that it breaks with tools that compile one file at a time.
Enums:
- An
enumis one of the few TypeScript features that produces runtime JavaScript: an object that holds the members. - Numeric enums also create a reverse mapping, from value back to name.
- String enums are nominal. Nominal means TypeScript matches them by name, not by shape. So you must write
Status.Idle, and you cannot pass the plain string"idle".
String literal unions:
- They have no runtime cost.
- They accept plain strings.
- They work well with JSON and APIs.
- They narrow naturally.
If you also need the values at runtime, for a dropdown for example, an as const object plus a derived union gives you both.
The const enum caveat: a const enum is inlined at compile time, meaning each use is replaced by its value. This needs type information from other files. So it does not fit tools that compile one file at a time, like Babel, esbuild or SWC. The isolatedModules option makes TypeScript check that every file can be compiled alone. Bundlers and Next.js rely on it. With it on, using an ambient const enum from another file is an error. Ambient means declared only as a type, for example in a .d.ts file, with no runtime code.
- Many frontend teams prefer string literal unions over enums.
- Enums produce runtime code, and numeric enums also have reverse mappings from value to name.
- String enums are nominal, so you must use
Status.Idle. Unions accept plain strings. - Unions cost nothing at runtime, and an
as constobject also gives you runtime values. const enuminlining clashes withisolatedModulesand with tools that compile one file at a time.
- Enums (https://www.typescriptlang.org/docs/handbook/enums.html)typescriptlang.org
- TSConfig reference (https://www.typescriptlang.org/tsconfig)typescriptlang.org