Last updated: Feb 26, 2024
Reading time·3 min
Use an intersection type to extend a type in TypeScript. Intersection types
are defined using an ampersand &
and are used to combine existing object
types.
You can use the &
operator as many times as necessary to construct a type.
type TypeA = { name: string; }; type TypeB = TypeA & { age: number; }; type TypeC = TypeB & { country: string; }; const employee: TypeC = { name: 'Bobby Hadz', age: 30, country: 'Chile', };
Intersection types
are defined by using the &
operator and allow us to extend existing object
types.
You can also use an intersection type to add a property to an existing type.
type Employee = { id: number; name: string; }; // 👇️ use intersection type type Person = Employee & { country: string; }; const person: Person = { id: 1, name: 'Bobby Hadz', country: 'Germany', };
You can also use an intersection type to combine existing object types.
type TypeA = { name: string; }; type TypeB = { age: number; country: string; }; type TypeC = TypeA & TypeB; const employee: TypeC = { name: 'Bobby Hadz', age: 30, country: 'Chile', };
You can use the &
operator to extend the object type with an already-defined
interface as well.
type TypeA = { name: string; age: number; }; interface InterfaceA { country: string; } type TypeB = TypeA & InterfaceA; const employee: TypeB = { name: 'Bobby Hadz', age: 30, country: 'Chile', };
You can use the &
operator as many times as necessary to construct a type.
type TypeA = { name: string; }; type TypeB = { country: string; }; type TypeC = { age: number; }; type TypeD = TypeA & TypeB & TypeC; const employee: TypeD = { name: 'Bobby Hadz', age: 30, country: 'Chile', };
If you have to extend an interface with a type, you have to use the extends keyword.
type TypeA = { name: string; country: string; }; interface InterfaceA extends TypeA { age: number; } const employee: InterfaceA = { name: 'Bobby Hadz', age: 30, country: 'Chile', };
If you have to extend an interface with multiple types, separate the types with a comma.
type TypeA = { name: string; }; type TypeB = { country: string; }; interface InterfaceA extends TypeA, TypeB { age: number; } const employee: InterfaceA = { name: 'Bobby Hadz', age: 30, country: 'Chile', };
An easy way to think about the &
operator and the extends
keyword is that we
copy the members of other named types and add new members to construct a new
type.
Extending a type is useful because it signals to the reader of the code that the types are related in some way.
You can use the Omit
utility type to override the type of one or more
properties when extending a type.
type TypeA = { id: string; name: string; }; type TypeB = Omit<TypeA, 'id'> & { id: number; // 👈️ override the type of the property age: number; country: string; }; const employee: TypeB = { id: 100, name: 'Bobby Hadz', age: 30, country: 'Chile', };
TypeA defines an id
property of type string
, however, the employee
object
should have an id
of type number.
The Omit utility type constructs a new type by picking the properties from the provided type and removes the specified keys.
We practically remove the id
property from TypeA
and specify the id
property in TypeB
with a new type.
The main benefits of using intersection types are:
If you need to do this with multiple properties, use the pipe |
character.
type TypeA = { id: string; height: string; name: string; }; type TypeB = Omit<TypeA, 'id' | 'height'> & { id: number; height: number; age: number; country: string; }; const employee: TypeB = { id: 100, height: 173, name: 'Bobby Hadz', age: 30, country: 'Chile', };
The code sample overrides the type of the id
and height
properties by
excluding them from the type and specifying the properties with new types in
TypeB
.
You can learn more about the related topics by checking out the following tutorials: