How to extend types in Typescript

Photo by Kevin Ku
Photo by Kevin Ku

When working with TypeScript, you’ll frequently encounter scenarios where you need to merge or enhance existing types to craft a new, specialized one. Fortunately, TypeScript makes this process straightforward and user-friendly.

To extend a type in Typescript, you have multiple options:

Extend a type using an intersection type

The intersection type helps combine existing types. The intersection type is defined by the & operator. You can extend a type with a type, and a type with an interface too.


type Animal = {
    name: string;
    sharpTeeth: boolean;
    breathesWater: boolean;
}

interface Creature {
    huntPrey: () => void;
}

// Extend with type
type PetAnimal = Animal & { nickname: string }

// Extend with interface
type PredatorAnimal = Animal & Creature;

Extend an interface using the extends keyword

We can extend interfaces in Typescript by using the extends keyword.

For example we can write:

type Profile = {
    name: string,
    email: string,
    created_at: string | Date,
    updated_at: string | Date
}

interface UserProfile extends Profile {
    user_id: number
}

Extend multiple interfaces

Also in TypeScript, you can expand the functionality of a class or type by implementing multiple interfaces. To achieve this, utilize the extends keyword and list the interfaces/types you want to incorporate, separating them with commas.

type BakedGood = {
    glutenFree: boolean;
    dairyFree: boolean;
}

type DessertGood = {
    frosted: boolean;
}

interface Pastry extends BakedGood, DessertGood {
    filling: string;
}

Extending Classes?

In Typescript you can even extend classes with an interface.

class Post {
    private title: string;
    private content: string;
}

interface FrontPagePost extends Post {
    getHeaderImage(): void;
}

Omit a type

You can employ the Omit utility type to override the types of one or more properties when extending another type.

type GroceryItem {
    id: string;
    name: string;
    price: number;
    refridgerated: boolean;
}

type BookstoreItem = Omit<GroceryItem, 'refridgerated'> & {
    section: string;
}

// Omit multiple items by using the pipe symbol |
type LibraryItem = Omit<GroceryItem, 'refridgerated' | 'price'> & {
    deweyDecimal: string;
}

The Omit utility type creates a fresh type by selecting properties from the given type and excluding the designated keys


Profile picture

Written by who lives and works in Wisconsin building useful things, and thinks that pineapple on pizza is okay. You should follow them on Twitter