Kodokon kodokon.com

Enums and const assertions: the modern alternatives

Understand the limits of enums and derive your types from frozen constants with as const.

7 min · 3 questions

Open this lesson in Kodokon

enum has been part of the language since its early days, and you'll run into it in plenty of codebases. It groups named constants under a single type, usable both as a value and as an annotation.

TYPESCRIPT
enum Role {
  User = "USER",
  Admin = "ADMIN",
}

function canDelete(role: Role): boolean {
  return role === Role.Admin;
}
A classic string enum

Yet the modern ecosystem is moving away from it. An enum is syntax that doesn't exist in JavaScript: the compiler emits an object at runtime, which complicates certain tools and is incompatible with the erasableSyntaxOnly option. The alternative: a plain object frozen with as const, from which you derive the type.

TYPESCRIPT
const ROLES = {
  User: "USER",
  Admin: "ADMIN",
} as const;

type Role = (typeof ROLES)[keyof typeof ROLES];

function canDelete(role: Role): boolean {
  return role === ROLES.Admin;
}
An as const object with a derived type, the modern equivalent

as const also works on arrays: each element becomes a read-only literal, and (typeof SIZES)[number] produces the union of the values. A single source of truth feeds both the running code and the types.

TYPESCRIPT
const SIZES = ["sm", "md", "lg"] as const;

type Size = (typeof SIZES)[number];

function isSize(value: string): value is Size {
  return (SIZES as readonly string[]).includes(value);
}
An as const array: iterable at runtime, a union at the type level

Knowledge check

Make sure you remember the key points of this lesson.

  1. What major difference separates an enum from an object frozen with as const?
    • An enum is TypeScript-specific syntax that generates code, while an as const object remains plain JavaScript
    • An as const object is slower at runtime
    • An enum can only contain numbers
  2. What does as const produce when applied to the array ['sm', 'md']?
    • string[]
    • A read-only tuple of literal types
    • A mutable array of type Array<'sm' | 'md'>
    • A compile error
  3. How do you get the union of the values of a ROLES object frozen with as const?
    • keyof typeof ROLES
    • (typeof ROLES)[keyof typeof ROLES]
    • typeof ROLES