An interface describes the shape that a class must provide. It declares properties and methods but supplies neither implementations nor a constructor. Classes conform with the implements keyword, while remaining free to add members of their own. section 11.4 section 11.6
Use interfaces when several classes should share a type contract:
- Require common members such as name and getDetails while allowing each class to implement them differently. section 11.4
- Implement several contracts by listing interfaces after implements, provided overlapping properties do not have conflicting types. section 11.4.1
- Extend an interface so the derived contract includes the parent’s members and adds new requirements. section 11.4.2
- Mark properties or methods optional with ?, then check for their presence before using them. section 11.4.3
One contract, two implementations
interface Person {\n name: string;\n getDetails(): string;\n}\n\nclass Employee implements Person {\n constructor(public name: string, private dept: string) {}\n getDetails() { return `${this.name} works in ${this.dept}`; }\n}\n\nclass Customer implements Person {\n constructor(public name: string, public creditLimit: number) {}\n getDetails() { return `${this.name} has ${this.creditLimit} limit`; }\n}\n\nlet data: Person[] = [\n new Employee("Fidel Vega", "Sales"),\n new Customer("Alice Jones", 500)\n];
Interfaces exist only during type checking. The compiler emits no interface details into JavaScript, so instanceof cannot narrow an interface type. Check for a distinguishing property instead, such as getDetails in a Person-or-Product union. section 11.4.5
Listing 11.27 Type guarding an interface in the index.ts file in the src folder
interface Person {
name: string;
getDetails(): string;
}
interface Product {
name: string;
price: number;
}
class Employee implements Person {
constructor(public name: string, public company: string) {
// no statements required
}
getDetails() {
return `${this.name} works for ${this.company}`;
}
}
class SportsProduct implements Product {
constructor(public name: string, public category: string,
public price: number) {
// no statements required
}
}
let data: (Person | Product)[] = [new Employee("Bob Smith", "Acme"),
new SportsProduct("Running Shoes", "Running", 90.50),
new Employee("Dora Peters", "BigCo")];
data.forEach(item => {
if ("getDetails" in item) {
console.log(`Person: ${item.getDetails()}`);
} else {
console.log(`Product: ${item.name}, ${item.price}`);
}
});
Compare Person and Product objects in a union, then narrow them with the in operator. section 11.4.5






