type PickMembers<T, K extends keyof T> = {
[P in K]: T[P]
};
type BadCallback = (arg?: any) => void;
class FakeEventEmitter {
data: {
[key: string]: BadCallback[];
} = {};
on(name: string, callback: BadCallback) {
if (!this.data[name]) {
this.data[name] = [];
}
this.data[name].push(callback);
}
emit(name: string, data?: any) {
if (!this.data[name]) {
return;
}
this.data[name].forEach(cb => {
cb(data);
});
}
}
type KeysOfType<
Terface,
Filter,
K extends keyof Terface = keyof Terface
> = K extends (Terface[K] extends Filter ? K : never) ? K : never;
interface TypedEventEmitter<
Events,
VoidKeys extends KeysOfType<Events, void> = KeysOfType<Events, void>,
NotVoidKeys extends Exclude<keyof Events, VoidKeys> = Exclude<keyof Events, VoidKeys>
> {
on<K extends NotVoidKeys>(
eventName: K,
callback: (payload: Events[K]) => void
) : void;
emit<K extends NotVoidKeys>(eventName: K, payload: Events[K]) : void;
on<K extends VoidKeys>(
eventName: K,
callback: () => void
) : void;
emit<K extends VoidKeys>(eventName: K) : void;
}
type StrictEventEmitter<Events,EventEmitter> = TypedEventEmitter<Events> &
PickMembers<
EventEmitter,
Exclude<keyof EventEmitter, keyof TypedEventEmitter<Events>>
>;
interface Point {
x: number;
y: number;
}
interface Events {
BasicMessage: string;
NumberMessage: number;
PosMsg: Point;
VoidMsg: void;
}
const ee: StrictEventEmitter<Events, FakeEventEmitter> = new FakeEventEmitter();
ee.emit("VoidMsg");
ee.emit("PosMsg", 145);
ee.emit("PosMsg", { x: 1, y: 2 });
Comments
0 B
|👍
/👎
0 B
|👍
/👎