模仿多重继承

时间:2015-12-11 21:12:45

标签: inheritance typescript multiple-inheritance mixins prototypal-inheritance

有一个类First和构造函数Second。我正在尝试创建一个类Both作为他们两个孩子。更准确的说,我是从构造函数原型到子类原型的复制方法。

我明白这不是真正的遗产,但这对我来说已经足够了。

还有其他问题。如何使打字稿接受复制的方法?

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];
}

事实上,我需要将metods看得更深一些:

class Final extends Both {
  doIt() {
    this.someMethod();
    //this.doSmth(); // How to make this call threated as correct?
    (this as any as IBoth).doSmth(); // That compiles, but it's awfull
  }
}

如果在这种情况下方法在类Both中不可见,那就没关系。

我已经尝试过了:

  1. 写作时

    class Both extends First implements IBoth {
    

    typesctipt说我没有实现接口方法。

  2. Both重命名为_Both并使用

    var Both = _Both as typeof _Both;
    

    与原始代码存在相同的问题,因为First从未被指导过。

  3. 如果我将Both重命名为_Both并写入

    var Both = _Both as typeof IBoth;
    

    打字稿无法找到IBoth

  4. 还有其他方法可以达到吗?

    您可以尝试http://www.typescriptlang.org/Playground
    Full code there

    添加此行并运行代码(将代码从右侧面板复制到浏览器控制台):

    (new Final).doIt();
    

    未注释行this.doSmth();时的输出:

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

    PS:Same question in Russian.

2 个答案:

答案 0 :(得分:4)

试试这个:

class Both extends First {
  constructor() {...}
  doSmth: typeof Second.prototype.doSmth;
}

Demo

Second作为一个类而不是一个函数也更好。如果这是一个javascript模块,请添加一个声明文件。

最后,如果您不能拥有Second的类型,只需为每个函数添加类型:

class Both extends First {
  constructor() {...}
  doSmth: () => void;
}

答案 1 :(得分:1)

不需要界面。只需要通过

声明一个原型字段
doSmth: () => void

它作为一种财产可见,而不是一种方法,但没关系。

完整列表:

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:应该为typescript class prototype variable谷歌而不是关于继承的不同组合。