TypeScript Best Practices

Chapter 2 · Practice 4 of 6

Use literal unions and as const instead of loose strings and enums

From Modeling data with types

Why it matters

A parameter typed string accepts typos. A union of string literals, such as 'asc' | 'desc', accepts only the values that work, and editors autocomplete them.

When you also need the values at runtime, for a dropdown or validation, declare them once with as const and derive the type from the array or object. That gives you one source of truth, no drift between the list and the type, and erasable syntax that every tool can strip.

Prefer this over enum. Enums generate JavaScript, so they fail under Node's type stripping and erasableSyntaxOnly, and numeric enums accept numbers that are not members.

Do

  • Derive union types from an as const array or object
  • Narrow string parameters to the literals your code actually supports

Avoid

  • Numeric enums, which accept values outside the declared members

Example

TypeScript
export const SORT_ORDERS = ['asc', 'desc'] as const;
export type SortOrder = (typeof SORT_ORDERS)[number]; // 'asc' | 'desc'

export function isSortOrder(value: string): value is SortOrder {
  return (SORT_ORDERS as readonly string[]).includes(value);
}