-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheventEmitter.ts
executable file
·35 lines (31 loc) · 1007 Bytes
/
eventEmitter.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
type EventMap = Record<string, any>
type EventKey<T extends EventMap> = string & keyof T
type EventReceiver<T> = (params: T) => void
interface Emitter<T extends EventMap> {
on<K extends EventKey<T>>(eventName: K, fn: EventReceiver<T[K]>): () => void
off<K extends EventKey<T>>(eventName: K, fn: EventReceiver<T[K]>): void
emit<K extends EventKey<T>>(eventName: K, params: T[K]): void
}
// `listeners` are unbounded -- don't use this in practice!
function eventEmitter<T extends EventMap>(): Emitter<T> {
const listeners: {
[K in keyof EventMap]?: ((p: EventMap[K]) => void)[]
} = {}
return {
on(key, fn) {
listeners[key] = (listeners[key] || []).concat(fn)
return () => this.off(key, fn)
},
off(key, fn) {
listeners[key] = (listeners[key] || []).filter((f) => f !== fn)
},
emit(key, data) {
;(listeners[key] || []).forEach(function (fn) {
fn(data)
})
},
}
}
export const appEmitter = eventEmitter<{
loading: boolean
}>()