2016-06-25 11 views
4

typescriptでこのパターンに似たものを得るにはどうすればよいですか?Typescript子クラスの関数オーバーロード

class A { 
    Init(param1: number) { 
     // some code 
    } 
} 

class B extends A { 
    Init(param1: number, param2: string) { 
     // some more code 
    } 
} 

それが動作するはずのように上記切り取らコードは、しかしHow Typescript function overloading worksの精査の上、それはエラーがスローされていることを理にかなって、表示されます。

TS2415: 'Class 'B' incorrectly extends base class 'A'. 
Types of property 'Init' are incompatible. 

私はコンストラクタ関数は、この動作が許可されていることを知っているが、Iこれらのオブジェクトはメモリ効率のためにプールされるため、コンストラクタはここでは使用できません。私は初期化(の別の定義を提供することができ

)クラスAでは:

class A { 
    Init(param1: number, param2: string): void; 
    Init(param1: number) { 
     // some code 
    } 
} 

しかし、これは今、基本クラスはその派生クラスのすべてについて知っておく必要があるので、理想的な未満です。

第3のオプションは、クラスBのInitメソッドの名前を変更することですが、それはかなり醜く混乱するだけでなく、ベースクラスのInit()メソッドを公開しているため、検出が困難なバグ基本クラスInit()が間違って呼び出されたとき。

上記の方法の落とし穴がないこのパターンを実装する方法はありますか?

答えて

3

TypeScriptは、メソッドが互換性を持たないと不平を言っています。次の場合はどうなりますか?

let a:A = new A(); // a is of type A 
a.Init(1) 
a = new B(); // a is still of type A, even if it contains B inside 
a.Init(1) // second parameter is missing for B, but totally valid for A, will it explode? 

あなたはS BAを遵守するための署名を」は、変更、交換可能で、それらを必要としない場合:

class B extends A { 
    Init(param1: number, param2?: string) { // param 2 is optional 
     // some more code 
    } 
} 

しかし、あなたはあなたがする必要がある状況で自分自身を見つけるかもしれません

class C extends A { 
    Init(param1: string) { // param 1 is now string instead of number 
     // some more code 
    } 
} 

この場合、現在のクラスと基本クラスcalの両方を満たすメソッドシグネチャのリストを追加しますls。

class C extends A { 
    Init(param1: number) 
    Init(param1: string) 
    Init(param1: number | string) { // param 1 is now of type number | string (you can also use <any>) 
     if (typeof param1 === "string") { // param 1 is now guaranteed to be string 
      // some more code 
     } 
    } 
} 

このように、Aクラスは、派生クラスのいずれかについて知る必要はありません。トレードオフとして、基本クラスとサブクラスの両方のメソッド呼び出しを満たすシグネチャのリストを指定する必要があります。

+0

ご回答ありがとうございます。私はそれを避けることができる場合は、実行時の型チェックを行う必要はありませんが好きですが、Typescriptは他のほとんどのことを防ぐために管理しています。 – Daniel

+0

残念ながら、サブクラスのメソッドシグネチャがベースクラスのシグネチャと一致しない場合は、ランタイムチェックなしでは実行できません。私の最初の例を見てみましょう:誰かがあなたのサブクラスを実際にベースクラスであるかのように呼んでいるかもしれません – zlumer

+0

ああ、今、私は今理解していると思います。おそらく私は両方のクラスを抽象基本クラスから他の共通のプロパティを継承させるでしょう。 – Daniel

関連する問題