How to extend a Type in TypeScript

avatar
Borislav Hadzhiev

Last updated: Feb 26, 2024
3 min

banner

# Table of Contents

  1. Extend a Type in TypeScript
  2. Add a property to an existing Type in TypeScript
  3. Extending a Type with an already defined interface
  4. Extending an Interface with a Type in TypeScript
  5. Overriding the type of a Property when extending a Type

# Extend a Type in TypeScript

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.

index.ts
type TypeA = { name: string; }; type TypeB = TypeA & { age: number; }; type TypeC = TypeB & { country: string; }; const employee: TypeC = { name: 'Bobby Hadz', age: 30, country: 'Chile', };

extend type in typescript

The code for this article is available on GitHub

Intersection types are defined by using the & operator and allow us to extend existing object types.

# Add a property to an existing Type in TypeScript

You can also use an intersection type to add a property to an existing type.

index.ts
type Employee = { id: number; name: string; }; // 👇️ use intersection type type Person = Employee & { country: string; }; const person: Person = { id: 1, name: 'Bobby Hadz', country: 'Germany', };

add property to existing type

The code for this article is available on GitHub

You can also use an intersection type to combine existing object types.

index.ts
type TypeA = { name: string; }; type TypeB = { age: number; country: string; }; type TypeC = TypeA & TypeB; const employee: TypeC = { name: 'Bobby Hadz', age: 30, country: 'Chile', };

# Extending a Type with an already defined interface

You can use the & operator to extend the object type with an already-defined interface as well.

index.ts
type TypeA = { name: string; age: number; }; interface InterfaceA { country: string; } type TypeB = TypeA & InterfaceA; const employee: TypeB = { name: 'Bobby Hadz', age: 30, country: 'Chile', };

extending type with already defined interface

The code for this article is available on GitHub

You can use the & operator as many times as necessary to construct a type.

index.ts
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', };

# Extending an Interface with a Type in TypeScript

If you have to extend an interface with a type, you have to use the extends keyword.

index.ts
type TypeA = { name: string; country: string; }; interface InterfaceA extends TypeA { age: number; } const employee: InterfaceA = { name: 'Bobby Hadz', age: 30, country: 'Chile', };

extending interface with type

The code for this article is available on GitHub

If you have to extend an interface with multiple types, separate the types with a comma.

index.ts
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.

# Overriding the type of a Property when extending a Type

You can use the Omit utility type to override the type of one or more properties when extending a type.

index.ts
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', };

overriding type of property when extending type

The code for this article is available on GitHub

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:

  1. Reducing duplication, because we don't have to copy properties between interfaces.
  2. Signaling intent to the reader of our code that there is a relation between the two types.

If you need to do this with multiple properties, use the pipe | character.

index.ts
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.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.