-
Notifications
You must be signed in to change notification settings - Fork 0
/
eventHelper.ts
108 lines (91 loc) · 3.19 KB
/
eventHelper.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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
type IAnyFunction<T = any> = (...args: any) => T
interface IEventLike {
on?: (eventName: string, callback: IAnyFunction) => any
once?: (eventName: string, callback: IAnyFunction) => any
emit?: (eventName: string, ...args: any) => any
off?: (eventName: string, callback: IAnyFunction) => any
offAll?: (eventName: string) => any
}
interface IEventOnOptions {
/** 只触发一次 */
once?: boolean
}
/** 使用函数的形式, 可以取到对应的类型或者注释 */
export function eventHelper<
KV extends Record<string, string> = Record<string, string>,
KF extends Record<string, IAnyFunction> = Record<string, IAnyFunction>
> (event: IEventLike, options: {
keyValue?: KV
keyFunction?: KF
} = {}) {
type EventTypes = KV & KF
const { keyValue, keyFunction } = options;
// 把函数形式的event key取出来,生成 { key: key }
const keyFnName = {} as {
[T in keyof KF]: T
};
if (keyFunction) {
Object.keys(keyFunction).forEach((key: keyof typeof keyFnName) => {
keyFnName[key] = key;
});
}
// 所有event的keyname
const eventKeys = {
...keyValue,
...keyFnName,
};
const emitPropertyDescriptorMap: PropertyDescriptorMap = {};
const onPropertyDescriptorMap: PropertyDescriptorMap = {};
const offPropertyDescriptorMap: PropertyDescriptorMap = {};
Object.keys(eventKeys).forEach((key) => {
const realKey = eventKeys[key];
// emit
emitPropertyDescriptorMap[realKey] = {
get: () => (...args) => {
if (event.emit) {
return event.emit(realKey, ...args);
}
}
};
// on
onPropertyDescriptorMap[realKey] = {
get: () => (callback, options: IEventOnOptions = {}) => {
if (options.once && event.once) {
return event.once(realKey, callback);
}
if (event.on) {
return event.on(realKey, callback);
}
}
};
// off
offPropertyDescriptorMap[realKey] = {
get: () => (callback) => {
if (!callback && event.offAll) {
return event.offAll(realKey);
}
if (event.off) {
return event.off(realKey, callback);
}
}
};
});
const emit = Object.defineProperties({} as {
[T in keyof EventTypes]: EventTypes[T] extends IAnyFunction ?
EventTypes[T] :
(...args: any) => void
}, emitPropertyDescriptorMap);
const on = Object.defineProperties({} as {
[T in keyof EventTypes]: EventTypes[T] extends IAnyFunction ?
(callback: EventTypes[T], options?: IEventOnOptions) => void :
(callback: (...args: any) => void, options?: IEventOnOptions) => void
}, onPropertyDescriptorMap);
const off = Object.defineProperties({} as {
[T in keyof EventTypes]: (/** 如果不传callback,则删除该event下的所有事件 */callback?: IAnyFunction) => void
}, offPropertyDescriptorMap);
return {
emit,
on,
off
};
}