In short
A value can sometimes be one of a few things: an ID could be a string or a number, a request could be loading, done or failed. Union types say exactly that.
A type formed by combining multiple types with `|`, meaning a value can be one of several possible types (e.g. `string | number`).

Think of it like this
Veg or non-veg thali
At the mess counter you get either the veg thali or the non-veg one, never something else. Before eating, you check which one you got. A union is 'this OR that', and TypeScript makes you check which one before you use it.
Watch it happen
Narrowing a Result
1/4r is a Result. Right now it could be any of the three shapes, so only status is safe to read.
The big ideas
What you need to know
Written with |
string | number means the value can be a string or a number.
Narrow before using
Check with typeof, ===, or in. Inside the if, TypeScript knows the exact type.
Literal unions
"sm" | "md" | "lg" allows only those three strings. Typos become errors.
Discriminated unions
Give each option a shared field like status. Checking it tells TypeScript which shape you have.
See it in code
Walk through the code
1type Result =2 | { status: "loading" }3 | { status: "success"; data: string[] }4 | { status: "error"; message: string };5 6function render(r: Result) {7 switch (r.status) {8 case "loading":9 return "Loading...";10 case "success":11 return r.data.join(", "); // data exists here12 case "error":13 return `Oops: ${r.message}`; // message exists here14 }15}1/4Three possible shapes, each with a status field that says which one it is.
Inside each case, TypeScript knows exactly which fields exist. Try reading r.data in the error case and you'll get an error.
Save yourself the pain
Common mistakes
Oops
Using a property that only some members of the union have, without checking.
Do this instead
Narrow first with a check like r.status === "success", then use the property.
Oops
Using separate booleans like isLoading, isError and hasData.
Do this instead
One discriminated union with a status field makes impossible combos, like loading and error together, impossible.
Your mission
Model a fetch request
Quick check
function show(id: string | number) { return id.toUpperCase(); } Why does this fail?
Go deeper
- 1Model a function parameter that accepts either a `string` or `number`.
- 2Practice narrowing a union type using `typeof` or `in` checks.
- 3Model a set of related states as a union of object shapes — a 'discriminated union'.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.