Typescript Interfaces

Aug 07, 2019

Let's revisit our discussion of interfaces for a moment and look at how they interact with classes. In the next example, we will enforce the IPoint interface upon the Point class. Classes can optionally inherit type information from interfaces using the implements keyword. The class will then be required to implement all of the interface members; otherwise, compile errors will occur:

interface IPoint {
    x: number;
    y: number;
}
class Point implements IPoint {
    constructor(public x: number, public y = 0) {
    }
}

As we discussed earlier, interfaces are a purely compile time construct. The JavaScript that is output from this example is completely identical to the JavaScript we just saw. I snuck in a shorthand method of defining instance variables on classes too. Decorating the constructor's parameters with the public or private keywords tells TypeScript to treat these objects as part of the type and not just initialization parameters.

Classes are not limited to implementing a single interface. Providing a comma separated list of interfaces after the implements keyword allows your class to provide implementations of a variety of different contracts. Let's make our Point class more useful by implementing a second interface, as follows:

interface IPoint {
    x: number;
    y: number;
}
interface ICompare {
    Compare(p2: IPoint): number;
}
class Point implements IPoint, ICompare {
    public x: number;
    public y: number;
     constructor(x: number, y = 0) {
        this.x = x;
        this.y = y;
    }
    public Compare(p2: IPoint): number {
        var p1Val = this.x * this.x + this.y * this.y;
        var p2Val = p2.x * p2.x + p2.y * p2.y;
        var result = p1Val - p2Val;
        if (result == 0) {
            return 0;
        } else if (result > 0) {
            return 1;
        } else {
            return -1;
        }
    }
}

The ability to enforce multiple interfaces on our classes provides us with the ability to use our objects in several different contexts. Keeping our interfaces simple allows them to be more reusable across our applications. We could have easily placed the Compare method on the IPoint interface and achieved the same result. However, as we will see later with a few tweaks, any number of types could implement the ICompare interface, which have no need for the members x and y. In this case, the Compare method determines the distance each point is from the origin and returns a number representing which one is farthest away. If the object performing the comparison is farther away, a positive value is returned. If the point that has been passed as a parameter is farther away then a negative value is returned. If the two points are equivalent distances from the origin then a value of zero is returned.

Neeraj Dana

Experienced Software Engineer with a demonstrated history of working in the information technology and services industry. Skilled in Angular, React, React-Native, Vue js, Machine Learning