0Pricing
TypeScript Academy · Lesson

Combining Literals into Unions

Build finite value sets by unioning literal types.

Combining Literals into Unions is a free TypeScript Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Unions of Literal Types

A union of literals models a value that must be exactly one of several known options. It is the backbone of state machines, enums, and well-typed APIs.

type Status = 'idle' | 'loading' | 'success' | 'error';

let state: Status = 'idle';
state = 'loading';
console.log('State:', state);

Switching on a Literal Union

A switch over a literal union reads cleanly and the compiler knows each case is one of the allowed values. This pairs perfectly with exhaustiveness checks.

type Status = 'idle' | 'loading' | 'done';

function label(s: Status): string {
  switch (s) {
    case 'idle': return 'Waiting';
    case 'loading': return 'Working';
    case 'done': return 'Finished';
  }
}
console.log(label('loading'));

Exhaustive Handling

Handling every member of a union is called exhaustive handling. When you cover all cases, TypeScript can prove the function always returns, with no missing branch.

type Dir = 'left' | 'right';

function step(d: Dir): number {
  if (d === 'left') return -1;
  return 1; // only 'right' remains
}
console.log(step('left'), step('right'));

The never Exhaustiveness Trick

Assigning the value to a never in the default branch forces a compile error if you ever add a new union member but forget to handle it. This is a safety net for evolving code.

type Shape = 'circle' | 'square';

function area(s: Shape): string {
  switch (s) {
    case 'circle': return 'pi r^2';
    case 'square': return 'a^2';
    default:
      const _exhaustive: never = s;
      return _exhaustive;
  }
}
console.log(area('circle'));

Deriving Unions From const Objects

A common pattern is to keep values in a const object and derive the union from its values using typeof obj[keyof typeof obj]. One source of truth, two outputs.

const Colors = { Red: 'red', Blue: 'blue' } as const;
type Color = typeof Colors[keyof typeof Colors];
// 'red' | 'blue'
const c: Color = Colors.Blue;
console.log(c);

Deriving Unions From Keys

You can also derive a union of the keys with keyof typeof obj. This is useful when the keys themselves are the meaningful identifiers.

const ICONS = { home: 0, search: 1, profile: 2 } as const;
type IconName = keyof typeof ICONS;
// 'home' | 'search' | 'profile'
const name: IconName = 'search';
console.log(name, ICONS[name]);

Discriminated Unions With Literal Tags

Attach a literal tag property to each object variant, and TypeScript can discriminate between them. Checking the tag narrows to the exact shape.

type Action =
  | { type: 'add'; amount: number }
  | { type: 'reset' };

function reduce(a: Action): number {
  if (a.type === 'add') return a.amount;
  return 0;
}
console.log(reduce({ type: 'add', amount: 5 }));

Narrowing by the Discriminant

Once you test the literal discriminant, the compiler knows which variant you have, so its unique fields become safely accessible without casts.

type Event =
  | { kind: 'click'; x: number; y: number }
  | { kind: 'key'; code: string };

function handle(e: Event): string {
  if (e.kind === 'key') return 'Key ' + e.code;
  return 'Click ' + e.x + ',' + e.y;
}
console.log(handle({ kind: 'key', code: 'Esc' }));

Combining Multiple Unions

You can compose larger unions from smaller named ones. This keeps related options grouped and reusable across your codebase.

type Primary = 'red' | 'blue' | 'yellow';
type Secondary = 'green' | 'orange';
type Color = Primary | Secondary;

const c: Color = 'green';
console.log(c);

Unions as Function Constraints

Passing a literal union to a function constrains callers to valid options and gives editor autocomplete. The combination of safety and discoverability is hard to beat.

type Align = 'left' | 'center' | 'right';

function setAlign(a: Align): void {
  console.log('Aligned', a);
}
setAlign('center');
// setAlign('top'); // Error

Why Literal Unions Beat Strings

Using a plain string parameter accepts any value, including typos. A literal union catches mistakes at compile time and documents valid choices — a clear upgrade for maintainable code.

type Method = 'GET' | 'POST' | 'PUT' | 'DELETE';

function request(m: Method, url: string): void {
  console.log(m, url);
}
request('POST', '/api/users');

Quick Check

Test your understanding of literal unions.

Recap: Combining Literals

You learned to:

  • Build unions of literals for finite option sets.
  • Handle them exhaustively, using the never trick for safety.
  • Derive unions from const objects via keyof typeof and typeof obj[keyof typeof obj].
  • Discriminate variants with literal tag properties.

Next course: the special unknown, never, and void types.

const ROUTES = { home: '/', about: '/about' } as const;
type Route = typeof ROUTES[keyof typeof ROUTES];
const r: Route = '/about';
console.log(r);

Frequently asked questions

Is the “Combining Literals into Unions” lesson free?

Yes — the full text of “Combining Literals into Unions” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.

What will I learn in “Combining Literals into Unions”?

Build finite value sets by unioning literal types. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start TypeScript Academy?

No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Combining Literals into Unions” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this TypeScript Academy lesson?

Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. String and Numeric Literal Types
  2. Boolean Literals and Literal Inference
  3. const Assertions with as const
  4. Combining Literals into Unions
← Back to TypeScript Academy