web-dev-qa-db-ja.com

TypeScriptでの複数クラスの継承

最大で1つの他のクラスしか拡張できないという問題を回避する方法は何ですか。

class Bar {

  doBarThings() {
    //...
  }

}

class Bazz {

  doBazzThings() {
    //...
  }

}

class Foo extends Bar, Bazz {

  doBarThings() {
    super.doBarThings();
    //...
  }

}

これは現在不可能です。TypeScriptはエラーを出します。インターフェイスを使用することで他の言語でこの問題を克服することはできますが、TypeScriptではそれらの問題を解決することはできません。

提案は大歓迎です!

10
nourikhalass

これはインターフェースで可能です:

interface IBar {
  doBarThings();
}

interface IBazz {
  doBazzThings();
}

class Foo implements IBar, IBazz {
  doBarThings() {}
  doBazzThings(){}
}

ただし、これをsuper/baseの方法で実装する場合は、次のような別のことを行う必要があります。

class FooBase implements IBar, IBazz{
  doBarThings() {}
  doBazzThings(){}
}

class Foo extends FooBase {
  doFooThings(){
      super.doBarThings();
      super.doBazzThings();
  }
}
1
Brocco

実際には問題の解決策ではありませんが、とにかく継承よりもコンポジションを使用することを検討する価値があります。

継承よりも構成を優先しますか?

0
spierala

これは、複数のクラスを拡張する際の私の回避策です。それはかなり甘い型安全性を可能にします。このアプローチの大きな欠点はまだ見つかっていません。多重継承を実行したいのと同じように機能します。

まず、ターゲットクラスに実装するインターフェイスを宣言します。

interface IBar {
  doBarThings(): void;
}

interface IBazz {
  doBazzThings(): void;
}

class Foo implements IBar, IBazz {}

次に、実装をFooクラスに追加する必要があります。これらのインターフェースも実装するクラスミックスインを使用できます。

class Base {}

type Constructor<I = Base> = new (...args: any[]) => I;

function Bar<T extends Constructor>(constructor: T = Base as any) {
  return class extends constructor implements IBar {
    public doBarThings() {
      console.log("Do bar!");
    }
  };
}

function Bazz<T extends Constructor>(constructor: T = Base as any) {
  return class extends constructor implements IBazz {
    public doBazzThings() {
      console.log("Do bazz!");
    }
  };
}

Fooクラスをクラスミックスインで拡張します。

class Foo extends Bar(Bazz()) implements IBar, IBazz {
  public doBarThings() {
    super.doBarThings();
    console.log("Override mixin");
  }
}

const foo = new Foo();
foo.doBazzThings(); // Do bazz!
foo.doBarThings(); // Do bar! // Override mixin
0
nomadoda