2017-07-20 34 views
1

私はTypescript 2.0でプロジェクトを手に入れました。es6を私のモジュールとして使用しています.Lib es2017が含まれているため、マップを使用できます。私はいくつかの不要なキャストをする必要があることを除いて、すべて機能している。es6でジェネリックを使用Typescriptで

static readonly gameStateMap: Map<GameState, Phaser.State> = new Map([ 
    [GameState.PONG, new PongState() as Phaser.State], 
    [GameState.BREAKOUT, new BreakoutState() as Phaser.State] 
]); 

は、なぜ私はPhaser.Stateにそれらをキャストする必要がありますか?彼らは両方とも直接Phaser.Stateを伸ばしているので、私は問題なくマップにそれらを貼り付けることができるはずだと思った。

私は多分私はちょうど私のジェネリック宣言を洗練するために必要なと思ったので、私が試した:

Map<GameState, V extends Phaser.State>を。

この構文はTypescript's generics docsで使用されています。

しかし、動作しません。これはES6の一般的なものですか?それは私の問題ですか?キャストする必要がないようにこれを修正するにはどうすればよいですか?

また、この問題は問題のクラスが異なるプロパティを持つ場合にのみ発生します。エラーは次のとおりです。

error TS2345: Argument of type '((GameState | PongState)[] | (GameState | BreakoutState)[])[]' is not assignable to parameter of type 'Iterable<[GameState, State]>'. 

答えて

2

システムに問題があります。あなたはより多くの情報を提供する必要があります。それはplayground

enum GameState { 
    PONG, 
    BREAKOUT 
} 

namespace Phaser { 
    export interface State { } 
} 

class PongState implements Phaser.State { } 
class BreakoutState implements Phaser.State { } 


let gameStateMap: Map<GameState, Phaser.State> = new Map([ 
    [GameState.PONG, new PongState()], 
    [GameState.BREAKOUT, new BreakoutState()] 
]); 

UPDATEで働いている

: あなたが直面している問題は、手動で型を宣言し、推測に頼るということです。推論はそんなにしかできません。この場合、2つの内部配列は共通の型に推論することができないため、[{}, {}]となります。 ソリューションは、直接ジェネリックを使用することです:

enum GameState { 
    PONG, 
    BREAKOUT 
} 

namespace Phaser { 
    export interface State { } 
} 

class PongState implements Phaser.State { a: string } 
class BreakoutState implements Phaser.State { b: string } 


let gameStateMap = new Map<GameState, Phaser.State>([ 
    [GameState.PONG, new PongState()], 
    [GameState.BREAKOUT, new BreakoutState()] 
]); 
+0

私は作るためにあなたの運動場で遊んそれはもっと私のコードに似ていて、クラスの宣言をこれに変更することで問題を再現することができました: 'class PongState imaserments Phaser.State {stuff:string; } 'class BreakoutStateはPhaser.State {notStuff:number;}を実装します。 } '。この問題は、クラスに異なるプロパティが含まれている場合にのみ発生します。 – CorayThan

1

あなたはこの方法でそれを書くとき

let gameStateMap: Map<GameState, Phaser.State> = new Map(...) 

コンパイラはまず、それが宣言された型と互換性のあるかどうかを確認する、その後、new Mapのための型を推論しようgameStateMap

異なる型の要素を含む配列が含まれている場合、コンパイラは共通型を推論することができず、代わりに型を使用します。Map引数の型は明らかに[GameState, Phaser.State][]です。

コンパイラはあなたがMapコンストラクタに明示的な一般的な引数を与えることによって、それを提供することができ、その後、あなたがgameStateMapの明示的な型宣言を省略することができ、これで少しの助けを必要とします:

enum GameState { PONG, BREAKOUT }; 
namespace Phaser { 
    export interface State { } 
} 

class PongState implements Phaser.State { a: string } 
class BreakoutState implements Phaser.State { b: string} 

let gameStateMap = new Map< GameState, Phaser.State > ([ 
    [GameState.PONG, new PongState()], 
    [GameState.BREAKOUT, new BreakoutState()] 
]); 
関連する問題