liveBook · Manning

Interface

As explained in Essential TypeScript 5, Third Edition

An interface is a TypeScript type declaration that specifies the properties and methods a class must provide without implementing those members or defining a constructor.

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

How Essential TypeScript 5, Third Edition covers it

How deep it goes
Explains declarations, implementation, extension, optional members, merging, and runtime guarding, but does not describe emitted interface code.
Examples
Uses Person, Employee, Customer, DogOwner, Product, arrays, optional dog details, and property-based narrowing.
What it assumes
Assumes familiarity with JavaScript classes and TypeScript types while teaching interface syntax and class conformance.
What you can do after
Apply it to define class contracts, compose interfaces, handle optional members, and narrow interface-like unions safely.
How it connects
Connects interfaces with classes, abstract classes, shape types, union types, type guards, and generic types.

Also explained in

Compare how 7 books explain interface →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Essential TypeScript 5, Third Edition. The section links point to the parts of the book it draws on.