There is a class and a constructor function. An attempt is made to implement a class that is something like a descendant of both. More precisely, the methods from the prototype of the constructor function are copied into the prototype of the descendant class inherited from the class.

Yes, I understand that this is not a complete inheritance, but this is enough to solve the problem.

The problem is different. How to force a typing script to take copied methods?

class First { someMethod() { console.log('someMethod from First'); } } function Second() { console.log('Second'); } Second.prototype.doSmth = function () { console.log('doSmth from Second'); } interface IBoth { someMethod() doSmth() } class Both extends First /* implements IBoth */ { constructor() { console.log('constructor of Both'); super(); Second.call(this); } } for (let key in Second.prototype) { Both.prototype[key] = Second.prototype[key]; } 

In fact, it is necessary to ensure the visibility of the methods one step further.

 class Final extends Both { doIt() { this.someMethod(); //this.doSmth(); // Надо заставить видеть метод тут (this as any as IBoth).doSmth(); // Компилируется, но это ужас } } 

if the methods are not visible from Both itself, then it will do.

Here is what I have already tried:

  1. When trying to write

     class Both extends First implements IBoth { 

    an error occurs that I do not implement the interface methods.

  2. When renaming Both in _Both and using

     var Both = _Both as typeof _Both; 

    everything remains as it was, which is logical, since First is not used here.

  3. When renaming Both in _Both and using

     var Both = _Both as typeof IBoth; 

    says he can't find the name IBoth .

I tried a few more options, but they are absolutely crazy.
What else can you do?


You can try it here: http://www.typescriptlang.org/Playground
Full verification code

Run (code from the right panel) after adding the line:

 (new Final).doIt(); 

Output at startup with the uncommented line this.doSmth();

 constructor of Both Second someMethod from First doSmth from Second doSmth from Second 

PS: This question is in English.

1 answer 1

The interface is not needed at all, you just need to declare a prototype field with the desired type:

 doSmth: () => void 

It is visible as a property, not as a method, but it is not fundamental.

Full code:

 class First { someMethod() { console.log('someMethod from First'); } } function Second() { console.log('Second'); } Second.prototype.doSmth = function () { console.log('doSmth from Second'); } class Both extends First { constructor() { console.log('constructor of Both'); super(); Second.call(this); } doSmth: () => void } for (let key in Second.prototype) { Both.prototype[key] = Second.prototype[key]; } class Final extends Both { doIt() { this.someMethod(); this.doSmth(); //Both.prototype.doSmth(); // ok //Final.prototype.doSmth(); // ok } } 

PS: It was necessary to google not all sorts of options with inheritance, but typescript class prototype variable - immediately found a suitable option.