Yes, you're right. Interfaces are useful for type checking, while classes are beneficial when you require both type checking and additional methods or logic.
Personally, my approach is to start with an interface and then introduce a class when I need methods. I always advocate for having an interface, even if not using a class, as it allows for easier passing around or injecting without the need to instantiate the class multiple times.
For example, consider this common pattern when implementing methods in TypeScript:
interface IPerson {
firstName: string;
lastName: string;
age: number;
getFullName(): string;
}
class Person implements IPerson {
public firstName: string;
public lastName: string;
public age: number;
constructor(firstName: string, lastName: string, age: number) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
getFullName(): string {
return `${this.firstName} ${this.lastName}`
}
}
const person: IPerson = new Person('John', 'Doe', 44);
By following this method, I avoid the need to directly import or inject the Person
class unless necessary. Instead, I can work with the IPerson
interface seamlessly, accessing properties and methods as needed.
Alternatively, if I only require a data contract without methods:
interface IPerson {
firstName: string;
lastName: string;
age: number;
}
const person: IPerson = <IPerson>{
firstName: 'John',
lastName: 'Doe',
age: 44
};
This approach still allows for dynamic creation of variables adhering to the interface, though lacking methods like getFullName
.
In practice, I often use interfaces for structured JSON returns from HTTP responses on the frontend, eliminating the need for excessive class creation. However, some prefer creating classes for each response model.
Regarding efficiency, generating models can be time-consuming but pays off in the long run. Tools like C# Models to TypeScript npm package automate this process efficiently.
Another popular solution involves using Swagger Codegen to streamline model and service generation based on your backend specifications.
In conclusion, choose between interfaces and classes based on your specific requirements. Use classes for complex models requiring methods, and interfaces for simpler type structures. Remember, interfaces are optimized out in production, adding a performance advantage.
Find an example implementation here: Example Implementation