Interfaces in TypeScript

// Here's a basic interface for geometric shapes.
interface Geometry {
    area(): number;
    perim(): number;
}

// For our example we'll implement this interface on
// `Rect` and `Circle` classes.
class Rect implements Geometry {
    constructor(private width: number, private height: number) {}

    area(): number {
        return this.width * this.height;
    }

    perim(): number {
        return 2 * this.width + 2 * this.height;
    }
}

class Circle implements Geometry {
    constructor(private radius: number) {}

    area(): number {
        return Math.PI * this.radius * this.radius;
    }

    perim(): number {
        return 2 * Math.PI * this.radius;
    }
}

// If a variable has an interface type, then we can call
// methods that are in the named interface. Here's a
// generic `measure` function taking advantage of this
// to work on any `Geometry`.
function measure(g: Geometry): void {
    console.log(g);
    console.log(g.area());
    console.log(g.perim());
}

function main() {
    const r = new Rect(3, 4);
    const c = new Circle(5);

    // The `Circle` and `Rect` classes both
    // implement the `Geometry` interface so we can use
    // instances of these classes as arguments to `measure`.
    measure(r);
    measure(c);
}

main();

In TypeScript, interfaces are named collections of method signatures, similar to the concept in other languages. They define a contract that classes can implement.

In this example, we define a Geometry interface with area() and perim() methods. We then implement this interface for Rect and Circle classes.

The measure function demonstrates how interfaces can be used for polymorphism. It accepts any object that implements the Geometry interface, allowing us to use the same function for different shapes.

In the main function, we create instances of Rect and Circle and pass them to the measure function. This shows how different classes that implement the same interface can be used interchangeably.

To run this TypeScript code, you would typically compile it to JavaScript and then run it with Node.js:

$ tsc interfaces.ts
$ node interfaces.js
Rect { width: 3, height: 4 }
12
14
Circle { radius: 5 }
78.53981633974483
31.41592653589793

This example demonstrates how TypeScript’s interfaces can be used to define shared behavior across different classes, enabling polymorphism and more flexible code design.