Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

The way we can implement an Interface to an es6 class is pretty straightforward:

interface IDog {
    bark(): void
}

class Dog implements IDog {
    bark(): void {

    }
}

The question is: how to implement the same interface to this "class":

const Dog = function() {

}

Dog.prototype.bark = function() {

}

I tried defining the type of Dog as IDog: const Dog: IDog. Didn't work.

So, I need it to implement Dependency Inversion and I can't figure out how to do this with es5 classes. I saw that Classical Inheritance style is an "antipattern" in Javascript, so I decided to create classes the old way and need help implementing Typescript Interfaces to them.

like image 950
Seu Madruga Avatar asked Jul 09 '18 00:07

Seu Madruga


People also ask

Can we use class in ES5?

In the ES5 version, there are no classes; a function is used to make an object directly.

Can a class implement an interface TypeScript?

The Developer class implements the Employee and Person interfaces. A class can implement as many interfaces as necessary. When implementing an interface, you have to make sure to set all of the necessary properties and methods on the class.

How do I create an interface class in TypeScript?

It is used to create a structure for an entity. We can create a class by using the class keyword. We can create an interface by using the interface keyword. A class cannot disappear during the compilation of code.

Where should I put interfaces TypeScript?

You can store interfaces directly on the main file that use them. Like any other class, function or object, you can explicitly export and import types from . ts files. Maybe these are TS files that contain nothing but types.


1 Answers

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.

like image 91
artem Avatar answered Oct 12 '22 15:10

artem