Skip to content

Instantly share code, notes, and snippets.

@shahanahmed86
Created July 5, 2024 19:53
Show Gist options
  • Save shahanahmed86/dd7ccb3dce44298be6312d6f31675ddf to your computer and use it in GitHub Desktop.
Save shahanahmed86/dd7ccb3dce44298be6312d6f31675ddf to your computer and use it in GitHub Desktop.
Fixing Broken Event Emitter in Typescript
type Listener<T extends Array<any>> = (...args: T) => void;
class EventEmitter<EventMap extends Record<string, Array<any>>> {
private listeners: { [K in keyof EventMap]?: Set<Listener<EventMap[K]>>} = {};
private getListeners<K extends keyof EventMap>(eventName: K): Set<Listener<EventMap[K]>> {
return this.listeners[eventName] ?? new Set();
}
on<K extends keyof EventMap>(eventName: K, listener: Listener<EventMap[K]>) {
const listeners = this.getListeners(eventName);
listeners.add(listener);
this.listeners[eventName] = listeners;
}
emit<K extends keyof EventMap>(eventName: K, ...args: EventMap[K]) {
const listeners = this.getListeners(eventName);
for (const listener of listeners) listener(...args);
}
}
type User = { id: number; name: string }
type EventMap = {
login: [user: User],
logout: [],
}
const ev = new EventEmitter<EventMap>();
ev.on('login', (user) => {
console.log('user...', user)
})
ev.emit('login', { id: 1, name: 'shahan' });
ev.on('logout', () => {
console.log('logout')
})
ev.emit('logout')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment