TypeScript · Types that pay for themselves

What is a discriminated union?

Mediumdiscriminated-unionsstatenarrowingUpdated Oct 2026
Quiz this track

Short answer

A discriminated union gives each member a shared literal property, usually kind or type. Checking that property narrows the whole object, which makes state machines and API results safe to handle.

A discriminated union is a union of object types that share a literal discriminant property. Because the property has a different literal value in each member, checking it tells the compiler exactly which shape is present. The rest of the object's fields are then available without casts.

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

function render(state: State): string {
  switch (state.status) {
    case "success":
      return state.data.join(", ");
    case "error":
      return state.message;
    default:
      return state.status;
  }
}

Why the discriminant matters

  • The discriminant must be a literal type, not a broad string
  • Each member can carry fields that only make sense in that state
  • Checking the discriminant narrows the entire object
  • The pattern works with switch, if and user-defined guards
  • It makes impossible combinations unrepresentable

A common mistake is making variant fields optional on a single interface. That allows states like loading with data or success without data, which the type cannot prevent. Separate members with a literal discriminant model the real states more accurately.

Keep the discriminant value stable and unique. If two members share the same literal, the compiler cannot tell them apart and narrowing will not work as intended.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1Why must the discriminant be a literal type?
  2. 2How does switch narrow a discriminated union?
  3. 3What is the alternative to optional variant fields?
  4. 4Can a discriminated union have a default case?

Say it in the interview

A discriminated union puts a shared literal field on every variant. Checking that field narrows the entire object, so I can access variant-specific data safely. I use it for UI state, API results and state machines because it makes impossible states hard to represent. The key is that the discriminant is a literal type, not a broad string.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live TypeScript mock interview and get scored feedback on depth, clarity and confidence.