-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevent-emitter.ts
39 lines (33 loc) · 1.24 KB
/
event-emitter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { EventEmitter as BaseEventEmitter } from "eventemitter3";
export class EventEmitter<EventTypes extends ValidEventTypes = string | symbol> extends BaseEventEmitter<EventTypes> {
subscribe<T extends EventNames<EventTypes>>(
event: T,
fn: EventListener<EventTypes, T>,
destroy?: () => void,
): {
unsubscribe: () => void;
} {
this.addListener(event, fn);
return {
unsubscribe: () => {
this.removeListener(event, fn);
if (destroy) {
destroy();
}
},
};
}
}
/*
|--------------------------------------------------------------------------------
| Types
|--------------------------------------------------------------------------------
*/
type EventListener<T extends ValidEventTypes, K extends EventNames<T>> = T extends string | symbol
? (...args: any[]) => void
: (...args: ArgumentMap<Exclude<T, string | symbol>>[Extract<K, keyof T>]) => void;
type EventNames<T extends ValidEventTypes> = T extends string | symbol ? T : keyof T;
type ValidEventTypes = string | symbol | Record<string, unknown>;
type ArgumentMap<T extends Record<string, unknown>> = {
[K in keyof T]: T[K] extends (...args: any[]) => void ? Parameters<T[K]> : T[K] extends any[] ? T[K] : any[];
};