Skip to main content

What does "union narrowing" mean?

What a union type is

First, a reminder: a union type (A | B | C) is a type that can be one of several options.

javascript
type Result = string | number;

A variable of type Result can be a string or a number:

javascript
let value: Result; value = "hello"; // string value = 42; // number

But until TypeScript knows what exactly is inside right now, it will not let you use type-specific properties.

javascript
value.toFixed(); // Error - could be a string

What narrowing is

Narrowing is the process by which TypeScript reduces the set of possible types, based on checks in the code.


What union narrowing is

Union narrowing is narrowing a type from a union down to one or more specific members of that union, depending on logical conditions, operators, or checks.


Example 1. Narrowing with typeof

javascript
function printValue(value: string | number) { if (typeof value === "string") { // here value: string console.log(value.toUpperCase()); } else { // here value: number console.log(value.toFixed(2)); } }

TypeScript "narrowed" value from string | number down to string in one branch and number in the other.


Example 2. Narrowing with an in check

javascript
type Cat = { kind: "cat"; meow: () => void }; type Dog = { kind: "dog"; bark: () => void }; function makeSound(animal: Cat | Dog) { if ("meow" in animal) { // animal: Cat animal.meow(); } else { // animal: Dog animal.bark(); } }

Example 3. Narrowing through a literal property

javascript
type Shape = | { kind: "circle"; radius: number } | { kind: "square"; side: number }; function area(shape: Shape) { if (shape.kind === "circle") { // shape: { kind: "circle"; radius: number } return Math.PI * shape.radius ** 2; } else { // shape: { kind: "square"; side: number } return shape.side ** 2; } }

This is an example of discriminated union narrowing (narrowing by the discriminant, the kind key).


Example 4. Narrowing with instanceof

javascript
function logDate(d: Date | string) { if (d instanceof Date) { // d: Date console.log(d.toISOString()); } else { // d: string console.log(d.toUpperCase()); } }

Example 5. Narrowing with an == null check

javascript
function greet(name?: string | null) { if (name == null) { // name: null | undefined console.log("No name provided"); } else { // name: string console.log("Hello, " + name); } }

Example 6. Narrowing with custom type guards

You can declare your own "type filter" - a function that returns value is ...:

javascript
type Car = { wheels: 4; drive: () => void }; type Bike = { wheels: 2; pedal: () => void }; function isCar(v: Car | Bike): v is Car { return (v as Car).drive !== undefined; } function move(vehicle: Car | Bike) { if (isCar(vehicle)) { // vehicle: Car vehicle.drive(); } else { // vehicle: Bike vehicle.pedal(); } }

What TypeScript takes into account during narrowing

TypeScript can automatically analyze control flow:

  • if, else, switch
  • typeof
  • instanceof
  • in
  • ===, !==, ==, !=
  • null and undefined checks
  • custom guards (v is T)
  • return / throw / break (affect which branches remain possible)

An example of combined narrowing

javascript
function process(val: string | number | boolean | null) { if (typeof val === "string") { // val: string } else if (typeof val === "number") { // val: number } else if (val === null) { // val: null } else { // val: boolean (the remaining type) } }

Why this matters

Without narrowing, TypeScript could not guarantee type safety. It would not know which type is in use at a given point in the program, and would force you to write as Type everywhere.

Thanks to union narrowing, TypeScript can analyze the logic of the code and automatically pick the correct subtype.


Summary

TermMeaning
Union TypeA union of possible types (`A
NarrowingReducing the set of possible types based on conditions
Union NarrowingNarrowing specifically within a union of types
How it happensThrough typeof, instanceof, in, literal checks, guards
Main goalLetting TypeScript know exactly which type is used in each branch of the code

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.