2017-07-30 28 views
2

typescript 2.3で動作していたジェネリックスを使用していますが、typescript 2.4.1のより厳密な型指定の強制で壊れてしまいました。Typescript 2.4.1およびより一般的なジェネリック型の型/継承の継承

私はこの問題を示すために、この最小限のコードスニペットを書いた:

class A {} 
class B extends A {} 
function helloA(clazz: typeof A) {} 
helloA(B); // fine 

class C<T> { 
    private c: T; 
}; 
class D extends C<string> {} 
function helloC(clazz: typeof C) {} 
helloC(D); // breaks 

以下TSC 2.4.1からのエラー:

test.ts(11,8): error TS2345: Argument of type 'typeof D' is not assignable to parameter of type 'typeof C'. 
    Type 'D' is not assignable to type 'C<T>'. 
    Types of property 'c' are incompatible. 
     Type 'string' is not assignable to type 'T'. 

のでhelloA(B)作品、およびhelloC(D)以前は動作していましたが、今は壊れてしまいます( "noStrictGenericChecks"を追加すれば、私のtsconfigにはもちろん、それはコンパイルされます)。

private c: T;の部分を削除すると、それもコンパイルされます。私の実際のコードでは、このクラスメンバは実際には存在しますが、私が拡張するクラスは外部ライブラリからのものなので、削除できません。また、コンパイルすることもできます。

このコードをコンパイルして文字列型を保持する方法はありますか?

答えて

2

genericタイプのパラメータとして{}を推測しないtypeof Cを使用する方法はありません。幸いにも、あなたは別の方法でクラスのコンストラクタを参照することができます。

type Constructor<T> = { 
    new(...args: any[]): T; 
    readonly prototype: T; 
} 

function helloC<T>(clazz: Constructor<C<T>>) { } 
helloC(D); 

あなたはそれが型パラメータとしてstringを推測helloCにコールを調べて見ることができます。

希望に役立ちます!

+0

これは非常にスマートな解決策であり、完全に機能します。どうもありがとう! – jbar