Intersection Types
Intersection Types in TypeScript: A Beginner Friendly Deep Dive
If you have ever stared at the &
operator in TypeScript and wondered if it was some secret math trick, you are not alone.
Many beginners confuse intersections with unions and walk away puzzled.
This guide is here to clear that fog.
Why Intersection Types Matter
In everyday coding, you often need something to fulfill multiple roles. Imagine hiring someone who can both drive a delivery truck and cook in the kitchen. Instead of writing two separate job descriptions over and over, you can combine them. That is what intersection types do for your code. They let you compose features, avoid duplication, and enforce structure. Your codebase gets cleaner and safer, and you spend less time rewriting the same thing.
The Basics: What Are Intersection Types
An intersection type is the logical AND of types.
A value must satisfy all included types at once.
The ampersand symbol &
is the syntax.
type A = { a: number }
type B = { b: string }
type AandB = A & B
const obj: AandB = { a: 42, b: 'hello' }
Here obj
must contain both a
and b
.
Think of it as wearing two hats at once.
This is very different from a union (|
) where you can pick one hat or the other.
Intersection vs Union: AND vs OR
A union type lets a value be one of several options. An intersection type demands all conditions.
type U = { id: number } | { name: string }
type I = { id: number } & { name: string }
- With
U
, an object can have just anid
, just aname
, or both - With
I
, an object must have bothid
andname
Use unions for flexibility. Use intersections for enforcing structure.
Composing Object Types
One common pattern is merging smaller interfaces into richer models.
interface User {
id: number
username: string
}
interface Profile {
bio: string
avatar: string
}
type UserProfile = User & Profile
Now UserProfile
has both identity and profile info without repeating definitions. This keeps your types DRY and consistent.
Enforcing Multiple Constraints
Sometimes a function parameter needs to be more than one thing at once.
interface Logger {
log: (message: string) => void
}
interface Identified {
id: number
}
function logUser(user: Logger & Identified) {
user.log(`User ${user.id} logged in`)
}
The function only accepts objects that both log and have an id
. This guarantees correct behavior before the code even runs.
Props and Configurations
In UI frameworks, you often combine props from different sources. Instead of writing a giant interface, intersect smaller ones.
type OwnProps = { id: string }
type ReduxProps = { dispatch: () => void }
type Props = OwnProps & ReduxProps
This makes the final type clear and maintainable.
The same trick works for configuration objects where you want some fields flexible but others required,
such as enforcing a url
in a config while keeping the rest optional.
Quirks and Pitfalls
- Conflicting properties: If two types define the same property with incompatible types, the result collapses to
never
. Example:{ status: string } & { status: number }
has no possible values, because string and number have no overlap. - Forgetting requirements: Every property from every side must exist. Missing one causes errors.
- Wrong operator: Remember
&
means both. If you want either, use|
. - Overcomplexity: Too many intersections can make types unreadable. Break them into smaller parts when needed.
A quick debugging tip: if the compiler complains about never
, check if your intersection has incompatible overlapping fields.
Takeaway
Intersection types give you a way to say “this thing must have everything.” They are perfect for merging objects, enforcing constraints, and structuring complex systems. Use them when you need roles combined. Stick to unions when you want either or. With practice, intersections become a natural and powerful tool in your TypeScript toolbox.
Want to test this out? Try refactoring one of your interfaces by combining smaller ones with &
. Then hover over the type in your editor to see the merged result. If you hit a weird never
error, you now know why.
Stay Updated
Get the latest TypeScript tips, tutorials, and course updates delivered straight to your inbox.