Defining a generic interface is a fundamental concept in TypeScript that enhances code reusability and type safety. A generic interface allows you to create a blueprint for objects that can work with any data type while maintaining the integrity of the type system. This is particularly useful in scenarios where the exact type of data cannot be determined in advance, enabling developers to write more flexible and scalable code.
To create a generic interface, you use angle brackets to define one or more type parameters. These parameters can then be used within the interface to specify the types of properties or methods. Here’s a basic example:
interface GenericInterface<T> {
value: T;
getValue: () => T;
}
In the example above, the interface GenericInterface takes a type parameter T. The property value and the method getValue both utilize this type parameter, allowing the interface to be instantiated with any type.
Let’s consider a scenario where we want to create a data repository that can handle different types of data. We can define a generic interface for this purpose:
interface Repository<T> {
add(item: T): void;
get(id: number): T | null;
getAll(): T[];
}
Now, we can implement this interface for different data types:
class UserRepository implements Repository<User> {
private users: User[] = [];
add(user: User): void {
this.users.push(user);
}
get(id: number): User | null {
return this.users.find(user => user.id === id) || null;
}
getAll(): User[] {
return this.users;
}
}
class ProductRepository implements Repository<Product> {
private products: Product[] = [];
add(product: Product): void {
this.products.push(product);
}
get(id: number): Product | null {
return this.products.find(product => product.id === id) || null;
}
getAll(): Product[] {
return this.products;
}
}
T, consider using more descriptive names like DataType or Item to enhance code readability.<T extends SomeBaseClass>.By following these guidelines, you can effectively define and implement generic interfaces that enhance the flexibility and maintainability of your codebase.