TypeScript interfaces provide a powerful way to define the shape of objects, including their properties and methods. However, in some cases, you may need to override the properties of an interface to better fit a specific use case or to extend the functionality of an existing interface. In this article, we will explore various techniques for overriding properties in TypeScript interfaces and provide code samples to illustrate each method. Let's get started!

1,  Extending Interfaces

One of the simplest ways to override a property in a TypeScript interface is to extend the interface and redefine the property in the new interface. By using the extends keyword, you can create a new interface that inherits all the properties of the base interface and modify the properties as needed.

interface BaseUser {
  id: number;
  name: string;
  role: string;
}

interface AdminUser extends BaseUser {
  role: "admin"; // Override 'role' property
}

const adminUser: AdminUser = {
  id: 1,
  name: "Alice",
  role: "admin",
};

console.log(adminUser); // Output: { id: 1, name: 'Alice', role: 'admin' }

2,  Intersection Types

Intersection types are another way to override properties in TypeScript interfaces. By combining two or more types using the & operator, you can create a new type with the properties of both types, where properties from the latter type override those from the former.

interface BaseProduct {
  id: number;
  name: string;
  price: number;
  category: string;
}

interface ElectronicProduct {
  category: "Electronics";
}

type Laptop = BaseProduct & ElectronicProduct;

const laptop: Laptop = {
  id: 1,
  name: "MacBook Pro",
  price: 1500,
  category: "Electronics",
};

console.log(laptop); // Output: { id: 1, name: 'MacBook Pro', price: 1500, category: 'Electronics' }

3,  Using Generics and Mapped Types

Generics and mapped types can be used to create flexible interfaces that allow you to override properties based on generic type parameters. By using generics, you can create reusable and dynamic interfaces that adapt to various use cases.

interface Person<T> {
  id: number;
  name: string;
  extra: T;
}

type Employee = Person<{ position: string; salary: number }>;
type Customer = Person<{ loyaltyPoints: number }>;

const employee: Employee = {
  id: 1,
  name: "John",
  extra: {
    position: "Manager",
    salary: 80000,
  },
};

const customer: Customer = {
  id: 2,
  name: "Jane",
  extra: {
    loyaltyPoints: 500,
  },
};

console.log(employee); // Output: { id: 1, name: 'John', extra: { position: 'Manager', salary: 80000 } }
console.log(customer); // Output: { id: 2, name: 'Jane', extra: { loyaltyPoints: 500 } }

Conclusion

In this article, we explored various techniques for overriding properties in TypeScript interfaces, such as extending interfaces, using intersection types, and leveraging generics and mapped types. These methods allow you to create flexible and reusable interfaces that can adapt to different use cases and requirements.

By understanding these techniques, you can design more expressive and maintainable TypeScript applications. Whether you're extending existing interfaces to support new features, creating dynamic and reusable interfaces with generics, or combining types using intersection types.

If you are interested in similar posts, take a look at my home page to find similar articles.