Ich versuche herauszufinden, wie effizient stark typisierte Ereignisse zu meinem Projekt hinzugefügt werden, aber in ungeraden Problemen weiterlaufen. Im Idealfall würde Ich mag Lage sein, so etwas zu tun:Hinzufügen von Definitionen für stark typisierte Ereignisse
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);
Das erste Problem ist, dass anscheinend Tupel sind keine gültigen Typen für Ruhe Parameter trotz einfach der Haube sind Arrays von typisierten Elementen unter (ich glaube, daran wird gerade gearbeitet). Ich nehme an, das ist in Ordnung, wenn ich die emit
Methode vergebe, und meine Ereignisse nur auf Funktionstypen anstelle von Tupeln abbilden. Dies würde auch den Vorteil von ein paar zusätzlichen Informationen über die Argumente geben.
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) => {});
An dieser Stelle bin ich ratlos. IntelliSense kann die richtigen Signaturen für on
oder once
ableiten, aber die tatsächlichen Argumenttypen werden nur für das Ereignis mit den meisten Argumenten auf seinem Rückruf zurückgeschlossen, was keine für mich Sinn macht. Ich öffnete vor ein paar Tagen an issue, habe aber noch keine Antwort bekommen. Ich bin mir nicht sicher, ob das tatsächlich ein Fehler ist oder ob ich etwas übersehen habe.
Gibt es in der Zwischenzeit irgendwelche effizienten Möglichkeiten, dies zu tun? Ich habe darüber nachgedacht, nur Überlastungen meine Emitter-Klasse wie diese Zugabe (hier EventEmitter
wird nur der Knoten Typisierungen verwendet wird):
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);
}
Doch diese mir eine tatsächliche Umsetzung der on
in meiner Klasse haben erfordert, und wenn ich will Typen für once
oder emit
Ich muss alle meine Event-Definitionen duplizieren. Gibt es eine bessere Lösung?