Stop 07 · TypeScriptTopics · 5/12

Union

Part of the Frontend Developer Roadmap

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`).

The jaadu mascot at a mess counter checks which of two thalis it has been given.

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

Result
loading
success
error
data: string[]
message: string

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

ts
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

~20 min

Quick check

function show(id: string | number) { return id.toUpperCase(); } Why does this fail?

Go deeper

  1. 1Model a function parameter that accepts either a `string` or `number`.
  2. 2Practice narrowing a union type using `typeof` or `in` checks.
  3. 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.

Download
InsideEdge