Skip to content

Instantly share code, notes, and snippets.

@zakcodez
Created November 6, 2021 07:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zakcodez/faf4e830ebc4e89e89a17002e35a316b to your computer and use it in GitHub Desktop.
Save zakcodez/faf4e830ebc4e89e89a17002e35a316b to your computer and use it in GitHub Desktop.
An event emitter, with an event map
// Usage:
// interface FooEventMap {
// run: (arg1: string, arg2: number) => void;
// }
//
// class Foo extends Emitter<{ [K in keyof FooEventMap]: FooEventMap[K] }> {
// run() {
// this.emit("run", "First argument", 5);
// }
// }
class Emitter<M extends {
[K in string]: (...args: any[]) => void
} = { [K in string]: (...args: any[]) => void }> {
protected _events: { [K in keyof M]?: M[K][] } = {}
on<K extends keyof M>(event: K, listener: M[K]) {
this._events[event] = this._events[event] || [];
this._events[event].push(listener);
}
once<K extends keyof M>(event: K, listener: M[K]) {
this._events[event] = this._events[event] || [];
const newListener = (...args: any[]) => {
// @ts-ignore
this.off(event, newListener);
listener.apply(this, args);
}
// @ts-ignore
this.on(event, newListener);
}
off<K extends keyof M>(event: K, listener: M[K]) {
this._events[event] = this._events[event] || [];
const listeners = this._events[event];
const index = listeners.indexOf(listener);
if (index !== -1) listeners.splice(index, 1);
}
emit<K extends keyof M>(event: K, ...args: Parameters<M[K]>) {
this._events[event] = this._events[event] || [];
this._events[event].forEach((listener) => {
listener.apply(this, args);
});
}
}
export default Emitter;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment