Intersection types
Like union types, intersection types allow us to combine the properties of existing primitive and custom types to make composites.
Creating an intersection
Say you have the following three types:
type IConcert = {
date: number;
location: string;
band: string;
};
type IConference = {
date: number;
location: string;
keynoteSpeaker: string;
};
type IMeeting = {
date: number;
location: string;
agenda: string[];
};
Each type corresponds to a different event and has two properties in common with the other events: date
and location
.
Rather than repeat these properties for each individual type, we could create a general IEvent
type and apply this as an intersection to each of the individual event types:
// The common event type
type IEvent = {
date: number;
location: string;
};
// The intersection
type IConcert = IEvent & {
band: string;
};
type IConference = IEvent & {
keynoteSpeaker: string;
};
In the case of interfaces, instead of using
&
we would writeinterface IConcert extends IEvent
Alternative method
There is another equivalent way of intersecting the types. We could first define IConcert
and IConference
as their own types (without extends
or &
) and then intersect with, e.g., type IConcert = SelfStandingConcertType & IEvent.
Benefits of intersections
- It is more concise and we do not repeat ourselves needlessly
- Common properties can be modelled in one place which makes updates and changes much easier: we do not have to change multiple type declarations, just change the ‘master’ type that is intersected with the variants.
- It is more readable: we can see which properties are unique to the type without having to parse repeated properties.
Set theory: understanding errors
With intersections we literally use the & operator which discloses that the logic is equivalent to logical AND: a member of the intersection must have the properties of both types. In the case of primitive values this is impossible or, more accurately, it results in an empty set because, for example, string
and boolean
do not share any common values. This means you will get an error if you assign an intersection type to a value that does not have all the features of each custom type in the intersection.