This guide is written for developers who want a practical answer, not a giant theory dump. The goal is to help you understand the decision, use the idea in a real project, and explain it clearly in an interview or code review.
Quick answer
A discriminated union is a set of object shapes that share one field, usually status or type, so TypeScript can narrow safely.
Why developers search this
Developers search this when boolean flags and optional fields start creating messy state handling.
It is a good SEO topic because the search usually happens near a real task: fixing a broken build, choosing an architecture pattern, deploying an app, reviewing AI-generated code, or preparing portfolio proof. Those searches are more valuable than broad “what is programming?” traffic because the reader needs an answer they can use today.
Mental model
Instead of storing many optional fields, describe each real state as its own shape. The compiler can then help you handle every case.
| State model | Risk |
|---|---|
| Many booleans | Impossible combinations like loading and success at the same time |
| Optional fields | You keep checking whether data exists |
| Discriminated union | Each state has exactly the fields it needs |
Practical example
type ApiState<T> =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: T }
| { status: "error"; message: string };
function renderUsers(state: ApiState<string[]>) {
switch (state.status) {
case "success":
return state.data.join(", ");
case "error":
return state.message;
default:
return state.status;
}
}
This example is intentionally small. In a real codebase, the surrounding details matter: naming, error handling, tests, runtime config, permissions, and how easy the next developer can understand the change.
Implementation checklist
- Choose one discriminator field.
- Make impossible states impossible.
- Keep each variant small.
- Use switch statements for exhaustive handling.
- Add a new variant only when the product has a real new state.
Common mistakes
- Adding
data?anderror?to every state. - Using boolean flags for mutually exclusive states.
- Forgetting empty states.
- Letting API response types leak directly into UI state.
- Skipping exhaustive checks when variants grow.
How to explain this in an interview
Use a concrete sentence:
I used this pattern because [problem]. The main tradeoff was [tradeoff]. I verified it by [test or check].
That structure works because it shows judgment. Anyone can name a tool. Strong developers explain why they chose it, what could go wrong, and how they checked the result.
Related guides
- react useeffect mistakes beginners
- typescript satisfies operator practical examples
- unknown vs any typescript difference
Sources checked
Final takeaway
A discriminated union is a set of object shapes that share one field, usually status or type, so TypeScript can narrow safely. Keep the implementation small, verify the edge cases, and write the decision down so the next person can trust it.
Discussion
What would you try, change, or challenge after reading this guide? Specific results and errors help the next reader.
Comments will load as you reach this section.