Hint
A literal type narrows a string/number/boolean to a specific value — combines with union for exhaustive enumerations
Literal types narrow a broad primitive type to a specific value. "circle" is a subtype of string, 42 is a subtype of number.
// String literals
type Direction = 'north' | 'south' | 'east' | 'west';
function move(dir: Direction) { /* only 4 valid inputs */ }
move('north'); // ✅
move('up'); // ❌ Error
// Numeric literals
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
// Boolean literals — useful for discriminated unions
type Result<T> =
| { success: true; value: T }
| { success: false; error: string };
function process(r: Result<number>) {
if (r.success) console.log(r.value); // narrows via boolean literal
else console.log(r.error);
}
const assertions — widen prevention:
// Without const — inferred as string
const dir = 'north'; // type: string (widened)
// With const — inferred as literal type
const dir2 = 'north' as const; // type: "north"
// Object with const — all properties become readonly literals
const config = { host: 'localhost', port: 3000 } as const;
// type: { readonly host: "localhost"; readonly port: 3000 }
// Array with const — tuple instead of array
const tuple = [1, 'a'] as const; // type: readonly [1, "a"]
as const is the modern replacement for enums in many cases. It's a plain JavaScript value (no runtime overhead) while providing the exhaustive type checking of an enum.