How to Extend an Interface in TypeScript

Updated: January 7, 2024 By: Guest Contributor Post a comment

Overview

TypeScript’s powerful type system includes an elegant way to combine interfaces – through extension. This tutorial guides you through the nuances of interface extension, improving your code’s type safety and reusability with practical examples.

Understanding Interfaces

An interface in TypeScript is a way to define the shape of an object. It can include a mix of method and property declarations. Defining an interface is simple:

interface Person {
    name: string;
    age: number;
}

Basic Interface Extension

To extend an interface, you simply declare a new interface and use the extends keyword:

interface Employee extends Person {
    employeeId: number;
}

This means every Employee is also a Person with an additional employeeId property.

Extending Multiple Interfaces

TypeScript allows an interface to extend multiple interfaces, combining their properties:

interface Contactable {
    email: string;
}

interface Employee extends Person, Contactable {
    employeeId: number;
}

Now, an Employee is a Person who can also be contacted via email.

Overriding Properties in Interface Extension

When extending interfaces, it is also possible to override property types for more specific needs:

interface PartTimeEmployee extends Employee {
    hoursWorkedPerWeek: number;
}

// Overriding age to be optional
interface YoungIntern extends PartTimeEmployee {
    age?: number;
}

Extending Interfaces with Methods

Next to properties, we can also declare methods in an interface extension:

interface Manager extends Employee {
    manageTeam: () => void;
}

Generics and Interface Extension

Generics add the ability to create flexible and reusable interfaces:

interface Repository<T> {
    findById(id: number): T | undefined;
}

interface UserRepo extends Repository<User> {}

Advanced Use Cases: Conditional Types

TypeScript’s conditional types can be used within interface extensions to create complex, dynamic type relationships:

interface Searchable<T> {
    search: T extends string ? (query: string) => T[] : never;
}

This creates a search method only if T extends string.

Combining Interfaces with Type Aliases

Sometimes you may want to combine interfaces not through extension but by creating a type alias:

type EmployeeDetails = Person & Contactable & { employeeId: number };

This method uses the type intersection operator & to combine types.

Best Practices

Even though TypeScript’s flexibility with interfaces is vast, it’s important to follow best practices such as preferring small, reusable interfaces and avoiding overextending.

Conclusion

Extending interfaces in TypeScript can lead to more maintainable and reusable code by building on existing type definitions. Whether you’re a beginner or advanced TypeScript user, continually practicing and refining the use of interfaces will surely pay off.