How to implement a Typescript interface to an es5-style “class”?

I assume that you want es5-style class implementation, which is declared to conform to IDog interface, and type-checked by the compiler to ensure that it really conforms to that interface.

Bad news – TypeScript does not support that. You can make TypeScript to think that es5 Dog is a class that implements IDog, but you have to declare DogConstructor interface and use as any as DogConstructor type assertion for Dog. And you can’t make TypeScript to typecheck prototype-based implemenation because Object.prototype (and subsequently Dog.prototype) is declared as any in the system library (see these issues for some discussion):

interface IDog {
    bark(): void
}

interface DogConstructor {
    new(): IDog;
}

const Dog = function (this: IDog) {
    // this.bark(); you can do this because of `this: IDog` annotation
} as any as DogConstructor;

Dog.prototype.bark = function() {

}

const p = new Dog();
p.bark();

I don’t think that support for this will ever be improved. Es5-style classes are usually implemented in javascript code which is not meant to be typechecked, and TypeScript provides enough support for writing type declarations that allow to use javascript implementation in type-safe way. If you are implementing classes in TypeScript, you can simply use real classes.

Leave a Comment