Union & Intersection Types
A union type ( A | B ) lets a value be one of several types, while an intersection type ( A & B ) combines several types into one that has all their members at once.
Learn Union & Intersection Types in our free TypeScript course — an interactive lesson with runnable examples, a practice exercise and a quick reference.
Part of the free TypeScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Think of a payment method. A union is "pay with cash OR card OR voucher " — at checkout you'll use exactly one of them, so the code must check which one before acting. An intersection is a VIP membership card that is also a payment card — a single object that is both at once, carrying the abilities of both. Union = a choice between alternatives; intersection = a mash-up that has it all.
1. Union Types: One of Several
A union is written with the pipe | and means the value can be any one of the listed types — for example string | number accepts both "ab12" and 42 . Because the value might be either, TypeScript only lets you use operations valid for every member until you narrow it. The most common narrowing tool is typeof , which you'll see below.
2. Intersection Types: All at Once
An intersection is written with the ampersand & and combines shapes: Person & Employee describes an object that has every property of Person and every property of Employee . It's the natural way to express "this thing is both a person and an employee", and at runtime you simply build one object carrying all the fields.
3. Discriminated Unions: The Best of Both
The most powerful pattern combines unions with a shared literal field. Give each member a common tag — often called kind or type — and a switch on that tag lets TypeScript narrow to the exact member in each branch. This discriminated union is how you model "one of several shapes" cleanly and safely.
🎯 Your Turn
Here's a classic union job: a function that accepts either a single string or an array of strings and always returns an array. Fill in the two blanks marked ___ , then run it.
No blanks this time — just a brief and a starting outline. Build the discriminated union handler yourself, run it, and check your output against the example in the comments.
Practice quiz
A union type A | B means a value is:
- Both an A and a B at once
- Neither A nor B
- Either an A or a B
- An array of A and B
Answer: Either an A or a B. A union means the value is one of the listed types — either an A or a B.
An intersection type A & B describes a value that:
- Has everything from A and everything from B
- Is one of A or B
- Has only the shared members
- Cannot be constructed
Answer: Has everything from A and everything from B. An intersection combines shapes; the value must have every member of both A and B.
Before using a string-only method on a string | number value you must:
- Cast it to any
- Use an intersection
- Nothing — it just works
- Narrow it first
Answer: Narrow it first. TypeScript only allows operations valid for every member until you narrow, e.g. with typeof.
Which operator commonly narrows a string | number union?
- keyof
- typeof
- infer
- extends
Answer: typeof. Inside if (typeof id === 'string') TypeScript treats id as a plain string in that branch.
A discriminated union relies on:
- A shared common literal field on each member
- Every member being a primitive
- Using & instead of |
- Having no fields at all
Answer: A shared common literal field on each member. A shared literal tag (often 'kind') lets a switch narrow to the exact member in each branch.
type Status = 'active' | 'paused' | 'closed' is an example of a:
- Intersection of objects
- Tuple type
- Union of string literals
- Mapped type
Answer: Union of string literals. It is a union of literal strings — a tidy, enum-like fixed set of allowed values.
Omitting a required property from an intersection type gives:
- A silent any
- A 'Property is missing' error
- An automatic union
- A readonly value
Answer: A 'Property is missing' error. An intersection requires all properties from both shapes, so missing one is an error.
Intersecting { x: string } & { x: number } makes property x:
- string
- number
- string | number
- never
Answer: never. Incompatible requirements for the same property collapse to never — no value can satisfy both.
Which is the 'or' tool versus the 'and' tool?
- | is and, & is or
- | is or, & is and
- Both are or
- Both are and
Answer: | is or, & is and. A rule of thumb: 'or' problems are unions (|), 'and' problems are intersections (&).
For a value that is EITHER a string OR a string[], the right type is:
Either/or alternatives are modelled with a union: string | string[].