Intersection types in TypeScript are used when you want to combine multiple types into a single type. We make use of the &
symbol to combine multiple types. For example,
type Animal = {
name: string,
height: number,
weight: number,
};
type Nature = {
friendly: boolean,
};
type Dog = Animal & Nature;
let dog: Dog = {
name: "Bruno",
height: 1,
weight: 1,
friendly: true,
};
console.log(dog); // {name: 'Bruno', height: 1, weight: 1, friendly: true}
In this example, we have a type Animal
that has name
, height
, and weight
properties. We also have a type Nature
which has property friendly
.
Now, we want to create a type Dog
that has both the properties of Animal
and Nature
. We can do so by using &
symbol which is used to insert types. So, we write
type Dog = Animal & Nature;
This way type Dog
can have properties of both Animal
and Nature
.
Similarly, the intersection is also possible on interfaces. We can rewrite the above code using the interface and the code should still work.
interface Animal {
name: string;
height: number;
weight: number;
}
interface Nature {
friendly: boolean;
}
type Dog = Animal & Nature;
let dog: Dog = {
name: "Bruno",
height: 1,
weight: 1,
friendly: true,
};
console.log(dog); // {name: 'Bruno', height: 1, weight: 1, friendly: true}
In this case, both Animal
and Nature
are interfaces and still, we can combine them.
Let’s look at another example, where two interfaces have the same property name and type.
interface Animal {
name: string;
weight: number;
}
interface Dog {
weight: number;
}
type Cat = Animal & Dog;
let cat: Cat = {
name: "Meemo",
weight: 1,
};
console.log(cat); // {name: 'Meemo', weight: 1}
In this case, we have the property weight
of the type number
in both interfaces. When we intersect both the interfaces for type Cat
, an object of Cat
will have a name
and a weight
property.
let cat: Cat = {
name: "Meemo",
weight: 1,
};
console.log(cat); // {name: 'Meemo', weight: 1}
What if the type of name
property is different in both interfaces? What do you think will happen?
interface Animal {
name: string;
weight: string;
}
interface Dog {
weight: number;
}
type Cat = Animal & Dog;
let cat1: Cat = {
name: "Meemo",
weight: 1, // ❌ Type 'number' is not assignable to type 'never'.
};
let cat2: Cat = {
name: "Cookie",
weight: "1", // ❌ Type 'string' is not assignable to type 'never'.
};
As you can see, there is no combinable type for string and number, hence, TypeScript will complain that you cannot assign it to type never
.