Skip to content

Instantly share code, notes, and snippets.

@stutrek
Created December 22, 2020 14:59
Show Gist options
  • Save stutrek/1df2448d787c5c775505969520487e8c to your computer and use it in GitHub Desktop.
Save stutrek/1df2448d787c5c775505969520487e8c to your computer and use it in GitHub Desktop.
type Listener<T extends Array<any>> = (...args: T) => undefined
type EventMap = {
[index: string]: any[]
}
class TypedEvents<Events extends EventMap> {
private events: {
[K in keyof Events]?: Listener<Events[K]>[]
} = {}
addEventListener<K extends keyof Events>(event: K, listener: Listener<Events[K]>){
this.events[event] = this.events[event] || [];
this.events[event].push(listener);
}
removeEventListener<K extends keyof Events>(event: K, listener: Listener<Events[K]>){
this.events = this.events || {};
if (event in this.events) {
const index = this.events[event].indexOf(listener);
if (index !== -1) {
this.events[event].splice(index, 1);
}
}
}
dispatch<K extends keyof Events>(event: K, ...data: Events[K]){
if (event in this.events) {
for (const listener of this.events[event]) {
listener(...data);
}
}
}
on = this.addEventListener;
off = this.removeEventListener;
emit = this.dispatch;
};
type MyEvents = {
boogersExcavated: [number],
consumptionComplete: [string]
}
const thing = new TypedEvents<MyEvents>()
thing.on('boogersExcavated', (num) => console.log(num));
thing.emit('boogersExcavated', 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment