網站搜尋

typescript - 模擬多重繼承


有一個類別 First 和建構函數 Second。我正在嘗試創建一個類別 Both 作為它們的子類。更準確地說,我正在將建構函數 prototype 中的方法複製到子類的 prototype 中。

我確實明白那不是真正的遺產,但對我來說已經足夠了。

還有其他問題。我如何才能讓 TypeScript 接受複製的方法?

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

事實上,我需要查看方法深入一層:

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 {
    

    TypeScript 說我還沒有實作介面的方法。

  2. 將 Both 重新命名為 _Both 並使用

    var Both = _Both as typeof _Both;
    

    留下和原始代碼相同的問題,因為 First 從未被提及。

  3. 如果我將 Both 重新命名為 _Both 並寫下

    var Both = _Both as typeof IBoth;
    

    TypeScript 找不到 IBoth。

還有其他方式到達那裡嗎?

你可以在 http://www.typescriptlang.org/Playground 嘗試
完整程式碼在那裡

添加這一行並運行代碼(將右側面板的代碼複製到你的瀏覽器控制台):

(new Final).doIt();

當這行 this.doSmth(); 未被註解時的輸出:

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

附註:同樣的問題用俄語。

答案#1

試試這個:

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

示範

最好將 Second 做為類別而不是函數。如果那是一個 JavaScript 模組,請添加宣告檔。

最後,如果你無法為 Second 指定類型,只需像這樣為每個函數添加類型:

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

答案#2

不需要介面。只需要透過宣告原型欄位即可

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

附註:本應該搜尋 typescript class prototype variable,而不是關於繼承的不同組合。