Discriminated Unions

The most powerful pattern in TypeScript for state management.

TypeScript5 min readConcept 17 of 54

The Tagged Union Pattern

A Discriminated Union (also known as a Tagged Union) is a union type made up of multiple object types that all share a single, common property with literal types (like a type, kind, or status string).

Because every object in the union has this shared property, TypeScript can use it to definitively identify which object shape it is currently looking at.

Perfect State Management

This is the cornerstone of robust TypeScript applications. It's the pattern used by Redux actions, useReducer in React, and finite state machines.

Instead of having one giant object where everything is optional ({ status: string, data?: Data, error?: Error }), you create distinct, mutually exclusive states. If status is 'loading', data doesn't even exist on the type. This makes invalid states mathematically impossible.

The Discriminant Property

typescript type State = | { status: "loading" } | { status: "success"; data: string[] } | { status: "error"; message: string }; function renderUI(state: State) { if (state.status === "success") { // TS knows this MUST be the success object. // 'data' is safely available. 'message' does not exist. console.log(state.data.length); } }

Try it

Select a state type and watch how TypeScript narrows the union, unlocking only the properties that belong to that specific state.

type State =
| { status: "loading" }
| { status: "success"; data: string[] }
| { status: "error"; error: string };

if (state.status === "loading") {
// TS narrows the union perfectly
// state has NO data or error properties!
}
Current Shape
{ status: "loading" }

Data and error properties are mathematically impossible to access.

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1Why is a Discriminated Union better than a single object with optional properties?

Remember this

  • A Discriminated Union requires a shared literal property across all objects (e.g., status).
  • Checking that shared property narrows the union to one specific object shape.
  • It prevents 'impossible states' by removing optional properties in favor of explicit state objects.
  • It is the standard pattern for Redux actions and complex state management.

Done with this concept?

Mark it complete to track your progress. No login needed.