Skip to main content
Practice Problems

Literal types in TypeScript

What are Literal Types?

Literal types allow you to specify the exact value a variable can hold โ€” not just a type like string or number, but a specific string, number, or boolean.


String Literal Types

typescript
type Direction = "up" | "down" | "left" | "right"; function move(dir: Direction) { console.log(`Moving ${dir}`); } move("up"); // โœ… move("left"); // โœ… move("diagonal"); // โŒ Error

Numeric Literal Types

typescript
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6; function roll(): DiceRoll { return Math.ceil(Math.random() * 6) as DiceRoll; } type HttpSuccessCode = 200 | 201 | 204; type HttpErrorCode = 400 | 401 | 403 | 404 | 500; type HttpStatusCode = HttpSuccessCode | HttpErrorCode;

Boolean Literal Types

typescript
type True = true; type False = false; type IsLoading = true | false; // Same as boolean

as const Assertion

as const makes values literal and readonly:

typescript
// Without as const โ€” widened to string[] const colors = ["red", "green", "blue"]; // type: string[] // With as const โ€” narrowed to readonly tuple of literals const colors = ["red", "green", "blue"] as const; // type: readonly ["red", "green", "blue"] type Color = typeof colors[number]; // "red" | "green" | "blue"

Object with as const

typescript
const config = { api: "https://api.example.com", timeout: 5000, retries: 3 } as const; // type: { readonly api: "https://api.example.com"; readonly timeout: 5000; readonly retries: 3 } type ApiUrl = typeof config.api; // "https://api.example.com" (literal, not string)

Practical Use Cases

Event Handling

typescript
type EventType = "click" | "focus" | "blur" | "submit"; function addEventListener(event: EventType, handler: () => void) { // ... }

Configuration Options

typescript
type LogLevel = "debug" | "info" | "warn" | "error"; type Theme = "light" | "dark" | "system"; type Size = "sm" | "md" | "lg" | "xl"; interface ButtonProps { size: Size; variant: "primary" | "secondary" | "outline" | "ghost"; disabled?: boolean; }

Discriminated Unions

typescript
type Shape = | { kind: "circle"; radius: number } | { kind: "rect"; width: number; height: number } | { kind: "triangle"; base: number; height: number }; function area(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius ** 2; case "rect": return shape.width * shape.height; case "triangle": return 0.5 * shape.base * shape.height; } }

Template Literal Types

Combine literal types with template strings:

typescript
type Color = "red" | "blue" | "green"; type Shade = "light" | "dark"; type ColorVariant = `${Shade}-${Color}`; // "light-red" | "light-blue" | "light-green" | "dark-red" | "dark-blue" | "dark-green"

Important:

Literal types bring enum-like safety without actual enums. Combined with union types and as const, they provide excellent type safety for configuration, event handling, and state management. Prefer literal unions over enums in most cases.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems