Skip to content

Instantly share code, notes, and snippets.

@bhumit070
Created April 15, 2023 05:10
Show Gist options
  • Save bhumit070/949935f8a87593891a1e9f1142aeafc3 to your computer and use it in GitHub Desktop.
Save bhumit070/949935f8a87593891a1e9f1142aeafc3 to your computer and use it in GitHub Desktop.
Type safe event emitter
type Listener<Args extends Array<any>> = (...args: Args) => void;
class MyEmitter<EventMap extends Record<string, Array<any>>> {
private eventListeners: {
[K in keyof EventMap]?: Set<Listener<EventMap[K]>>;
} = {};
constructor() {}
on<K extends keyof EventMap>(
eventName: K,
listener: Listener<EventMap[K]>,
) {
//super.on(eventName as string, listener as (...args: any) => void);
const listeners = this.eventListeners[eventName] ?? new Set();
listeners.add(listener);
this.eventListeners[eventName] = listeners;
}
emit<K extends keyof EventMap>(eventName: K, ...args: EventMap[K]) {
const listeners = this.eventListeners[eventName] ?? new Set();
for (const listener of listeners) {
listener(...args);
}
}
}
type User = {
name: string;
age: number;
};
type sUser = {
dob: Date;
city: string;
} & User;
type EventMap = {
login: [user: User];
signup: [user: sUser];
logout: [];
};
const emitter = new MyEmitter<EventMap>();
emitter.on('login', (user) => {
console.log(user);
});
emitter.on('signup', (user) => {
console.log('signup ', user);
});
emitter.emit('login', {
age: 10,
name: 'John',
});
emitter.emit('signup', {
age: 10,
city: 'New York',
dob: new Date(),
name: 'John',
});
@bhumit070
Copy link
Author

bhumit070 commented Apr 21, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment