TypeScript literal types and as const

A string literal type allows only specific strings. A union such as "UP" | "DOWN" is a precise alternative to a plain string, and the compiler rejects any other text. Writing the same list twice, once as values and once as a type, invites mistakes, so TypeScript can derive the type from the values.

TypeScript
const Direction = { Up: "UP", Down: "DOWN", Left: "LEFT", Right: "RIGHT" } as const;
type Direction = (typeof Direction)[keyof typeof Direction];

function turnRight(d: Direction): Direction {
  switch (d) {
    case "UP":
      return "RIGHT";
    case "RIGHT":
      return "DOWN";
    case "DOWN":
      return "LEFT";
    case "LEFT":
      return "UP";
    default: {
      const unreachable: never = d;
      return unreachable;
    }
  }
}

let heading: Direction = Direction.Up;
const path: string[] = [heading];
for (let i = 0; i < 4; i++) {
  heading = turnRight(heading);
  path.push(heading);
}
console.log(path.join(" -> "));

const levels = ["debug", "info", "warn", "error"] as const;
type Level = (typeof levels)[number];

function isLevel(text: string): text is Level {
  return (levels as readonly string[]).includes(text);
}

for (const text of ["warn", "verbose"]) {
  console.log(text + ": " + (isLevel(text) ? "valid level" : "not a level"));
}
Read the full lesson