TypeScript · Types that pay for themselves

What are union types and how do you use them safely?

Easyunionsnarrowingtype-systemUpdated Oct 2026
Quiz this track

Short answer

A union type means a value can be one of several types. You must narrow the value before using members that only exist on one branch.

Unions model alternatives. A parameter typed string | number can receive either, but the compiler only allows operations that are valid for every member. To use a string method, you first prove the value is a string with a runtime check.

ts
type Id = string | number;

function formatId(id: Id): string {
  if (typeof id === "string") {
    return id.toUpperCase();
  }

  return id.toFixed(0);
}
Inside the if branch, id is string. After the branch, it is number.

How to narrow a union

  • typeof for primitives such as string, number and boolean
  • in for checking whether a property exists on an object variant
  • instanceof for class instances
  • Equality against a literal for discriminated unions
  • User-defined type guards when the check is reusable

Unions are often better than a single wide type. They make the alternatives explicit and force every consumer to handle them. For object variants, add a shared literal field so narrowing is reliable and exhaustiveness can be checked later.

A union does not mean the value is interchangeable between members. Assigning a string to a string | number variable is fine, but calling a string-only method on the union is not.

Follow-ups you should expect

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

  1. 1Why can't you call a string method on a string | number value?
  2. 2What is the difference between a union and an intersection?
  3. 3How do you narrow a union of objects?
  4. 4When is a union better than a base interface?

Say it in the interview

A union means a value can be one of several types. I cannot call string methods until I narrow the value, for example with typeof. That forces me to handle each branch explicitly, which is exactly what I want for IDs or API results. The compiler then checks that every use is valid for the narrowed type.

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.