TypeScript Course
TypeScript
/
Advanced

Discriminated Unions

Definition

A pattern where you combine Union Types with a common, literal 'discriminant' property. This allows TypeScript to definitively narrow down which object type it is dealing with.

Explain Like I'm New

Imagine a box that either contains a Dog or a Bird. Both are 'Animals'. To figure out what's inside safely, you label the box with a `type: 'dog'` or `type: 'bird'` tag. TypeScript reads this tag (the discriminant), and instantly knows, 'Ah, it's a Bird, so it must have a wingspan property.'

Real World Example

Handling Redux actions! Every action has a `type` string (e.g., 'ADD_TODO'). TS looks at the `type`, and correctly infers what data should be in the `payload`.

Common Use Cases

  • •Redux Actions
  • •Handling diverse API response schemas
  • •State machines

Interactive Example

interface Circle { kind: "circle"; radius: number; }
interface Square { kind: "square"; sideLength: number; }
interface Rectangle { kind: "rectangle"; width: number; height: number; }

// The Union
type Shape = Circle | Square | Rectangle;

function getArea(shape: Shape) {
  // TypeScript doesn't know what shape it is yet.
  // console.log(shape.radius); // Error!

  switch (shape.kind) {
    case "circle":
      // TS knows 100% it's a circle here
      return Math.PI * shape.radius ** 2;
    case "square":
      // TS knows 100% it's a square here
      return shape.sideLength ** 2;
    case "rectangle":
      return shape.width * shape.height;
    default:
      // EXHAUSTIVENESS CHECKING:
      // If someone adds a 'Triangle' to the Shape union but forgets to 
      // add a case here, TS throws an error because Triangle cannot be assigned to never.
      const _exhaustiveCheck: never = shape;
      return _exhaustiveCheck;
  }
}

Interview Questions

basic

  • What is the 'discriminant' property?

intermediate

  • How do you narrow a discriminated union?

advanced

  • How do you ensure Exhaustiveness Checking using the `never` type?

Flash Cards

Question

What is the discriminant?

Click to reveal answer
Answer

It is a shared property across all objects in the union (usually called `type`, `kind`, or `status`) whose value is a unique String Literal. It acts as the ID tag for that specific shape.

Question

How do you narrow it?

Click to reveal answer
Answer

By using a `switch` or `if` statement on the discriminant property. Inside `case 'dog':`, TS narrows the union and allows access to Dog-specific properties.