2017-05-09 7 views
2

TypeScriptを使用するEventEmitterライクなシステムに強く型付けされたイベントを追加しようとしています。TypeScriptとEventEmitterの型付きイベント

interface EventHandler<T extends TypedMsg<any, any> { 
    on: (messageType: T.messageType, handler: (T.message) => void) => void; 
} 

をしかし、活字体がT.messageTypeのように抽出するサブタイプをサポートしていません:私はのようなインタフェースを定義したいと思います

interface TypedMsg<Name, T> { 
    messageType: Name; 
    message: T; 
} 

type TypedMsgFoo = TypedMsg<'FOO', string>; 
type TypedMsgBar = TypedMsg<'BAR', number>; 
type EitherFooOrBar = TypedMsgFoo | TypedMsgBar; 

は現在、我々は次のように私たちのタイプを定義します。これを行う別の方法がありますか?

最終目標はただで適切なタイピングとハンドラを定義するために、次のようになります。

class FooBarHandler implements EventHandler<EitherFooOrBar> { 
    on(messageType: EitherFooOrBar.messageType) {...} 
} 

答えて

3

活字体は、メンバーの種類を抽出する支援を行い、単に構文は少し珍しいです - それは

interface TypedMsg<Name, T> { 
    messageType: Name; 
    message: T; 
} 

type TypedMsgFoo = TypedMsg<'FOO', string>; 
type TypedMsgBar = TypedMsg<'BAR', number>; 
type EitherFooOrBar = TypedMsgFoo | TypedMsgBar; 

interface EventHandler<T extends TypedMsg<{}, {}>> { 
    on: (messageType: T['messageType'], handler: (m: T['message']) => void) => void; 
} 

class FooBarHandler implements EventHandler<EitherFooOrBar> { 
    on(
     messageType: EitherFooOrBar['messageType'], 
     handler: (m: EitherFooOrBar['message']) => void 
    ) { 

    } 
} 
indexed access type operatorと呼ばれています

しかし、すぐにタイプを明示的に入力してこれらの宣言をすべて入力するのはかなり退屈になります。タイプクリプトからタイプを推測できるようなもの、例えばこの質問のようなものを工夫したくなります:TypeScript type inference/narrowing challenge

関連する問題