Skip to main content

TypeScript analyzer

Enum Posture

Reports enum modernization posture: string enums representable as unions of literals, and const enums that isolatedModules transpilation cannot inline.

patterns ts-enum-posture

Enum Posture

Reports enum modernization posture: string enums representable as unions of literals, and const enums that isolatedModules transpilation cannot inline.

Enums are the one TypeScript feature that emits runtime code from type-level syntax, which puts them on the wrong side of two ecosystem shifts: single-file transpilers (esbuild, swc, isolatedModules) that cannot inline const enums across files, and type-stripping runtimes where enum syntax is not erasable at all. Neither makes enums wrong — they remain supported, nominal, and consistent — but a codebase should choose its posture deliberately. This analysis makes the posture visible: union-of-literals candidates are guidance-grade information, while a const enum in a project whose EFFECTIVE tsconfig enables isolatedModules is a proven build hazard, reported only when the flag is actually on (the tsconfig fact is injected by the config-owning surface; an unknown flag stays silent).

Severity guide

info
Union candidates are guidance for the next enum, not a migration mandate.
warning
const-enum-hazard fires only when the effective tsconfig proves isolatedModules is enabled.
critical
Not currently emitted by this analysis.

Examples

Before

const enum Status { Active = "active", Closed = "closed" }

After

type Status = "active" | "closed";
// or, when iterated at runtime:
const STATUS = { Active: "active", Closed: "closed" } as const;

Under isolatedModules a cross-file const enum access cannot be inlined; the erasable forms express the same contract with zero emitted code.

Remediation

Replace const enums under isolatedModules; treat union candidates as a standard to adopt at the next natural change.

For const-enum hazards: a union of string literals or an as const object preserves the contract and survives every transpilation mode; a plain enum is acceptable when the runtime object is genuinely wanted. For union candidates: do not mass-migrate — align on the standard and apply it when the enum next changes, since consistency within a codebase outweighs the pattern choice.

Documentation