Enum alternative

2 snippets in TypeScript

TSTypeScript

Literal Types

TS · Type Aliases
syntax
type Name = "exactValue" | "anotherValue";
type Name = 0 | 1 | 2;
example
type Direction = "north" | "south" | "east" | "west";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;

function move(direction: Direction, steps: number) {
  console.log(`Moving ${direction} by ${steps}`);
}

move("north", 3); // OK
// move("up", 3); // Error: Argument of type '"up"' is not assignable
output
// Literal types restrict a value to an exact set of allowed values

Note Literal types turn strings, numbers, or booleans into specific-value types. Combined with unions, they create powerful enumerations without the overhead of enum. const assertions (as const) automatically infer literal types.

Union Types as Enum Alternatives

TS · Enums
syntax
type Name = "value1" | "value2" | "value3";
example
// Instead of enum:
type Theme = "light" | "dark" | "system";

// Object const pattern for when you need both runtime values and types
const THEMES = {
  Light: "light",
  Dark: "dark",
  System: "system",
} as const;

type Theme2 = (typeof THEMES)[keyof typeof THEMES];
// "light" | "dark" | "system"

function applyTheme(theme: Theme2) {
  document.body.dataset.theme = theme;
}
output
// Union types achieve the same result without enum's quirks

Note Many TypeScript teams prefer string literal unions over enums for simplicity, full tree-shaking, and compatibility with --isolatedModules. The 'as const' object pattern gives you both runtime values (for iteration/lookup) and a derived type — the best of both worlds.