強く型付けされたイベントを私のプロジェクトに効率的に追加する方法を理解しようとしています。強く型付けされたイベントの定義を追加する
declare class EventEmitter<T> {
on<K extends keyof T>(event: K, fn: (...args: T[K]) => void, context?: any): void;
once<K extends keyof T>(event: K, fn: (...args: T[K]) => void, context?: any): void;
emit<K extends keyof T>(event: K, ...args: T[K]): boolean;
}
interface MyEvents {
'eventA': [string, number];
'eventB': [string, { prop: string, prop2: number }, (arg: string) => void];
}
class MyEmitter extends EventEmitter<MyEvents> {
// ...
}
const myEmitter = new MyEmitter();
myEmitter.on('eventA', (str, num) => {});
myEmitter.once('eventB', (str, obj, fn) => {});
myEmitter.emit('eventA', 'foo', 3);
最初の問題は、(私は信じているだけでボンネットの下に型指定された要素の配列であるにもかかわらず、明らかにタプルは、残りのパラメータのための有効なタイプではないということである。理想的には私はこのような何かを行うことができるようにしたいのですがこれは現在作業中です)。私はemit
メソッドをタイプして、イベントをタプルの代わりに関数型にマップさせても問題ないと思います。これはまた、議論が何であるかについての少し余分な情報の利益を与えるでしょう。
declare class EventEmitter<T> {
on<K extends keyof T>(event: K, fn: T[K], context?: any): void;
once<K extends keyof T>(event: K, fn: T[K], context?: any): void;
}
interface MyEvents {
'eventA': (str: string, num: number) => void;
'eventB': (
str: string,
data: { prop: string, prop2: number },
fn: (arg: string) => void
) => void;
}
class MyEmitter extends EventEmitter<MyEvents> {
// ...
}
const myEmitter = new MyEmitter();
myEmitter.on('eventA', (str, num) => {});
myEmitter.once('eventB', (str, obj, fn) => {});
この時点で私は困惑しています。 IntelliSenseはon
またはonce
の正しいシグネチャを推測できますが、実際の引数の型はコールバックで最も引数の多いイベントに対してのみ推測され、はとなります。私は数日前にan issueを開いたが、まだ回答を得ていない。私はこれが実際にバグか、何かを見落としているかどうかは分かりません。
一方、効率的な方法はありますか?私は(ここでEventEmitter
がちょうどノードタイピングを使用している)、このように私のエミッタクラスにオーバーロードを追加する方法について考えた:
class MyEmitter extends EventEmitter {
on(event: 'eventA', fn: (str: string, num: number) => void);
on(event: 'eventB', fn: (
str: string,
data: { prop: string, prop2: number },
fn: (arg: string) => void
) => void);
}
しかし、これは私のクラスでon
の実際の実装を持っている私を必要とし、I場合once
またはemit
のタイプが必要です。すべてのイベント定義を複製する必要があります。より良い解決策はありますか?