const c = "left"; // "left"let s = "left"; // string1type Align = "left" | "right" | "center";2let a: Align = "left";3a = "centre";a = "center";4enum Dir { Up, Down, Left, Right }5console.log(Dir.Left, Dir[2]);tsctype checker!✓slot 1"left"slot 2"right"slot 3"center"Up·Down·Left·Right·$ node align.js2 Left"left""centre""center"JS2
Back row: align.ts and tsc, the type checkerFront row: the allowed values of Align, the numbered members of Dir, and the laptop that runs align.jsTokens: values tested against the slots, the enum written as an object, and the number that is printedAt the back: align.ts, the code you write, and tsc, the type checker. In front: the type Align as a tray of its 3 allowed values, the enum Dir as 4 numbered cells, and a laptop running align.js. "left" fits a slot; the typo "centre" fits none and tsc reports error TS2820; "center" fits. The enum members are numbered 0, 1, 2, 3; the type is erased but the enum becomes an object, so Dir.Left and Dir[2] print 2 Left. Only numeric members get the number-to-name reverse mapping. String enums, such as enum Mode { On = "ON" }, map names to strings only.

Literal types

  1. A literal type is one exact value used as a type: "left" means only the text "left". Joined with |, the type Align allows exactly three strings: "left", "right", "center". Nothing else.

let and const

Enums

At run time

What happens

;; step 1/9 · literal
> 1  type Align = "left" | "right" | "center";

"left"     a literal type: one exact string
|          "or": a union of types
Align      = "left" | "right" | "center"
string     would allow any text at all

The "Did you mean" part (error TS2820) is what tsc 5.9 adds when an allowed value is spelled almost the same. With no close match the error is TS2322 without the suggestion. The align.js shown is what tsc 5.9 writes with no settings; its default target writes let as var. Other targets change small details, not the enum object.