Discriminated union

2 snippets in TypeScript

TSTypeScript

Union Types

TS · Type Aliases
Syntax
type Name = TypeA | TypeB | TypeC;
Example
type Status = "pending" | "active" | "archived";
type ApiResponse = SuccessResult | ErrorResult;

interface SuccessResult {
  ok: true;
  data: unknown;
}
interface ErrorResult {
  ok: false;
  errorCode: number;
  message: string;
}

function handleResponse(res: ApiResponse) {
  if (res.ok) {
    console.log(res.data); // narrowed to SuccessResult
  } else {
    console.error(res.message); // narrowed to ErrorResult
  }
}
Output
// Union means 'one of these types' - must narrow before accessing specific members

Note You can only access properties common to ALL members of a union without narrowing first. Use a shared discriminant property (like 'ok' above) to let TypeScript narrow automatically in conditionals.

Discriminated Unions

TS · Type Guards & Narrowing
Syntax
interface A { kind: "a"; ... }
interface B { kind: "b"; ... }
type Union = A | B;
Example
interface LoadingState {
  status: "loading";
}

interface SuccessState {
  status: "success";
  data: string[];
}

interface ErrorState {
  status: "error";
  errorMessage: string;
}

type RequestState = LoadingState | SuccessState | ErrorState;

function renderState(state: RequestState): string {
  switch (state.status) {
    case "loading":
      return "Loading...";
    case "success":
      return `Got ${state.data.length} items`; // data is available
    case "error":
      return `Error: ${state.errorMessage}`; // errorMessage is available
  }
}
Output
// Each case automatically narrows to the correct interface

Note A discriminated union has a common literal-typed property (the 'discriminant') shared across all members. TypeScript narrows exhaustively in switch/if on that property. This is the recommended pattern for modeling states, events, and message types.

Frequently asked questions

How does TypeScript handle discriminated union?
TypeScript covers this with 2 copy-ready snippets on this page. The "Union Types" snippet in TypeScript uses `type Name = TypeA | TypeB | TypeC;`.
Which code does the TypeScript example use?
The "Union Types" snippet uses `type Name = TypeA | TypeB | TypeC;`, from the Type Aliases section of the TypeScript cheat sheet.
What other TypeScript snippets are shown for "discriminated union"?
Besides "Union Types", this page also shows "Discriminated Unions".
Is there anything to watch out for?
Yes. For "Union Types": You can only access properties common to ALL members of a union without narrowing first. Use a shared discriminant property (like 'ok' above) to let TypeScript narrow automatically in conditionals.