-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.ts
148 lines (131 loc) · 4.88 KB
/
types.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
export type EvName = string;
export type Fn<
Params extends readonly unknown[] = readonly unknown[],
Result = unknown,
> = (...params: Params) => Result;
/**
* Returns a union type containing all the keys of an event map.
*/
export type EventNames<Map extends CustomEventMap> = keyof Map & EvName;
/**
* Interface for classes that aren't `EventEmitter`s, but still expose a
* strictly typed `emit` method.
*/
export interface TypedEventBroadcaster<EmitEvents extends CustomEventMap> {
emit<Ev extends EventNames<EmitEvents>>(
ev: Ev,
...args: CustomEventDetailParameter<EmitEvents, Ev>
): this;
}
export type TypedCustomEvent<
Type extends EvName,
Detail = unknown,
> = CustomEvent<Detail> & { type: Type };
export type EventTargetCompatible = Extract<
Parameters<EventTarget["addEventListener"]>[1],
Fn
>;
// for untyped emitter
// deno-lint-ignore no-explicit-any
export type CustomEventMap = Record<EvName, any>;
export type CustomEventListenerMap<
ReservedEvents extends CustomEventMap,
UserEvents extends CustomEventMap,
Ev extends ReservedOrUserEventNames<
ReservedEvents,
UserEvents
> = ReservedOrUserEventNames<ReservedEvents, UserEvents>,
> = Map<
ReservedOrUserListenerOnOrAddEventListener<ReservedEvents, UserEvents, Ev>,
ReservedOrUserListenerAddEventListener<ReservedEvents, UserEvents, Ev>
>;
export type CustomEventDetailParameter<
T extends CustomEventMap,
K extends keyof T,
> = unknown extends T[K] ? [detail?: unknown]
: undefined extends T[K] ? [detail?: T[K]]
: T[K] extends never ? []
: [detail: T[K]];
export type CustomEventCallbackAddEventListener<
Ev extends EvName = EvName,
Detail = unknown,
> = Fn<[event: TypedCustomEvent<Ev, Detail>], void>;
export type CustomEventCallbackOn<
Ev extends EvName = EvName,
Detail = unknown,
> = Fn<[event: TypedCustomEvent<Ev, Detail>["detail"]], void>;
/**
* Returns an untyped listener type if `T` is `never`; otherwise, returns `T`.
*
* This is a hack to mitigate https://github.com/socketio/socket.io/issues/3833.
* Needed because of https://github.com/microsoft/TypeScript/issues/41778
*/
export type FallbackToUntypedListener<T> = [T] extends [never]
// deno-lint-ignore no-explicit-any
? (...args: any[]) => void | Promise<void>
: T;
/**
* The event names that are either in ReservedEvents or in UserEvents
*/
export type ReservedOrUserEventNames<
ReservedEventsMap extends CustomEventMap,
UserEvents extends CustomEventMap,
> = EventNames<ReservedEventsMap> | EventNames<UserEvents>;
export type ReservedOrUserListenerParamsAddEventListener<
ReservedEvents extends CustomEventMap,
UserEvents extends CustomEventMap,
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>,
> = Parameters<
ReservedOrUserListenerAddEventListener<ReservedEvents, UserEvents, Ev>
>[0];
/**
* Type of a listener of a user event or a reserved event. If `Ev` is in
* `ReservedEvents`, the reserved event listener is returned.
*/
export type ReservedOrUserListenerOn<
ReservedEvents extends CustomEventMap,
UserEvents extends CustomEventMap,
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>,
> = FallbackToUntypedListener<
Ev extends EventNames<ReservedEvents>
? CustomEventCallbackOn<Ev, ReservedEvents[Ev]>
: Ev extends EventNames<UserEvents>
? CustomEventCallbackOn<Ev, UserEvents[Ev]>
: never
>;
export type ReservedOrUserListenerAddEventListener<
ReservedEvents extends CustomEventMap,
UserEvents extends CustomEventMap,
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>,
> = FallbackToUntypedListener<
Ev extends EventNames<ReservedEvents>
? CustomEventCallbackAddEventListener<Ev, ReservedEvents[Ev]>
: Ev extends EventNames<UserEvents>
? CustomEventCallbackAddEventListener<Ev, UserEvents[Ev]>
: never
>;
export type ReservedOrUserListenerOnOrAddEventListener<
ReservedEvents extends CustomEventMap,
UserEvents extends CustomEventMap,
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>,
> = FallbackToUntypedListener<
Ev extends EventNames<ReservedEvents> ?
| CustomEventCallbackAddEventListener<Ev, ReservedEvents[Ev]>
| CustomEventCallbackOn<Ev, ReservedEvents[Ev]>
: Ev extends EventNames<UserEvents> ?
| CustomEventCallbackAddEventListener<Ev, UserEvents[Ev]>
| CustomEventCallbackOn<Ev, UserEvents[Ev]>
: never
>;
export type ReservedOrUserListenerOnParams<
ReservedEvents extends CustomEventMap,
UserEvents extends CustomEventMap,
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>,
> = Parameters<ReservedOrUserListenerOn<ReservedEvents, UserEvents, Ev>>[0];
export type ReservedOrUserListenerAddEventListenerParams<
ReservedEvents extends CustomEventMap,
UserEvents extends CustomEventMap,
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>,
> = Parameters<
ReservedOrUserListenerAddEventListener<ReservedEvents, UserEvents, Ev>
>[0];