← Back to all tutorials

Interfaces with Classes

Implement interfaces in classes to enforce consistent contracts across different types.

Interfaces with Classes

Interfaces become powerful when used with classes — ensuring different classes follow the same contract.

The HasFormatter Interface

interface HasFormatter {
    format(): string;
}

Implementing the Interface

class Invoice implements HasFormatter {
    constructor(
        readonly client: string,
        private details: string,
        public amount: number
    ) {}

    format(): string {
        return `${this.client} owes $${this.amount} for ${this.details}`;
    }
}

class Payment implements HasFormatter {
    constructor(
        readonly recipient: string,
        private details: string,
        public amount: number
    ) {}

    format(): string {
        return `${this.recipient} was paid $${this.amount} for ${this.details}`;
    }
}

Using the Interface as a Type

let docOne: HasFormatter = new Invoice("Mario", "website", 250);
let docTwo: HasFormatter = new Payment("Luigi", "design", 300);

// Both work because they implement HasFormatter
let docs: HasFormatter[] = [];
docs.push(docOne);
docs.push(docTwo);

docs.forEach(doc => console.log(doc.format()));

Key Takeaways

  • implements forces a class to follow an interface
  • Different classes can implement the same interface
  • Interfaces as types let you group different classes together
  • Powerful for polymorphism and abstraction