@@ -59,25 +59,6 @@ function assertFunction(
59
59
}
60
60
}
61
61
62
- export const hasMatchFunction = < T > (
63
- v : Matcher < T >
64
- ) : v is HasMatchFunction < T > => {
65
- return v && typeof ( v as HasMatchFunction < T > ) . match === 'function'
66
- }
67
-
68
- export const isActionCreator = (
69
- item : Function
70
- ) : item is TypedActionCreator < any > => {
71
- return (
72
- typeof item === 'function' &&
73
- typeof ( item as any ) . type === 'string' &&
74
- hasMatchFunction ( item as any )
75
- )
76
- }
77
-
78
- /** @public */
79
- export type Matcher < T > = HasMatchFunction < T > | MatchFunction < T >
80
-
81
62
type Unsubscribe = ( ) => void
82
63
83
64
type GuardedType < T > = T extends ( x : any , ...args : unknown [ ] ) => x is infer T
@@ -147,11 +128,15 @@ export interface CreateListenerMiddlewareOptions<ExtraArgument = unknown> {
147
128
onError ?: ListenerErrorHandler
148
129
}
149
130
131
+ /**
132
+ * The possible overloads and options for defining a listener. The return type of each function is specified as a generic arg, so the overloads can be reused for multiple different functions
133
+ */
150
134
interface AddListenerOverloads <
151
135
Return ,
152
136
S = unknown ,
153
137
D extends Dispatch = ThunkDispatch < S , unknown , AnyAction >
154
138
> {
139
+ /** Accepts a "listener predicate" that is also a TS type predicate for the action*/
155
140
< MA extends AnyAction , LP extends ListenerPredicate < MA , S > > (
156
141
options : {
157
142
actionCreator ?: never
@@ -161,6 +146,8 @@ interface AddListenerOverloads<
161
146
listener : ActionListener < ListenerPredicateGuardedActionType < LP > , S , D >
162
147
} & ActionListenerOptions
163
148
) : Return
149
+
150
+ /** Accepts an RTK action creator, like `incrementByAmount` */
164
151
< C extends TypedActionCreator < any > > (
165
152
options : {
166
153
actionCreator : C
@@ -170,6 +157,8 @@ interface AddListenerOverloads<
170
157
listener : ActionListener < ReturnType < C > , S , D >
171
158
} & ActionListenerOptions
172
159
) : Return
160
+
161
+ /** Accepts a specific action type string */
173
162
< T extends string > (
174
163
options : {
175
164
actionCreator ?: never
@@ -179,6 +168,8 @@ interface AddListenerOverloads<
179
168
listener : ActionListener < Action < T > , S , D >
180
169
} & ActionListenerOptions
181
170
) : Return
171
+
172
+ /** Accepts an RTK matcher function, such as `incrementByAmount.match` */
182
173
< MA extends AnyAction , M extends MatchFunction < MA > > (
183
174
options : {
184
175
actionCreator ?: never
@@ -189,6 +180,7 @@ interface AddListenerOverloads<
189
180
} & ActionListenerOptions
190
181
) : Return
191
182
183
+ /** Accepts a "listener predicate" that just returns a boolean, no type assertion */
192
184
< LP extends AnyActionListenerPredicate < S > > (
193
185
options : {
194
186
actionCreator ?: never
@@ -211,19 +203,22 @@ interface RemoveListenerOverloads<
211
203
( type : string , listener : ActionListener < AnyAction , S , D > ) : boolean
212
204
}
213
205
206
+ /** A "pre-typed" version of `addListenerAction`, so the listener args are well-typed */
214
207
export type TypedAddListenerAction <
215
208
S ,
216
209
D extends Dispatch < AnyAction > = ThunkDispatch < S , unknown , AnyAction > ,
217
210
Payload = ListenerEntry < S , D > ,
218
211
T extends string = 'actionListenerMiddleware/add'
219
212
> = BaseActionCreator < Payload , T > &
220
- AddListenerOverloads < PayloadAction < Payload > , S , D >
213
+ AddListenerOverloads < PayloadAction < Payload , T > , S , D >
221
214
215
+ /** A "pre-typed" version of `middleware.addListener`, so the listener args are well-typed */
222
216
export type TypedAddListener <
223
217
S ,
224
218
D extends Dispatch < AnyAction > = ThunkDispatch < S , unknown , AnyAction >
225
219
> = AddListenerOverloads < Unsubscribe , S , D >
226
220
221
+ /** @internal An single listener entry */
227
222
type ListenerEntry <
228
223
S = unknown ,
229
224
D extends Dispatch < AnyAction > = Dispatch < AnyAction >
@@ -236,16 +231,13 @@ type ListenerEntry<
236
231
predicate : ListenerPredicate < AnyAction , S >
237
232
}
238
233
234
+ /** A "pre-typed" version of `createListenerEntry`, so the listener args are well-typed */
239
235
export type TypedCreateListenerEntry <
240
236
S ,
241
237
D extends Dispatch < AnyAction > = ThunkDispatch < S , unknown , AnyAction >
242
238
> = AddListenerOverloads < ListenerEntry < S , D > , S , D >
243
239
244
- export type TypedAddListenerPrepareFunction <
245
- S ,
246
- D extends Dispatch < AnyAction > = ThunkDispatch < S , unknown , AnyAction >
247
- > = AddListenerOverloads < { payload : ListenerEntry < S , D > } , S , D >
248
-
240
+ // A shorthand form of the accepted args, solely so that `createListenerEntry` has validly-typed conditional logic when checking the options contents
249
241
type FallbackAddListenerOptions = (
250
242
| { actionCreator : TypedActionCreator < string > }
251
243
| { type : string }
@@ -254,6 +246,7 @@ type FallbackAddListenerOptions = (
254
246
) &
255
247
ActionListenerOptions & { listener : ActionListener < any , any , any > }
256
248
249
+ /** Accepts the possible options for creating a listener, and returns a formatted listener entry */
257
250
export const createListenerEntry : TypedCreateListenerEntry < unknown > = (
258
251
options : FallbackAddListenerOptions
259
252
) => {
@@ -337,6 +330,7 @@ export const addListenerAction = createAction(
337
330
'actionListenerMiddleware/add' ,
338
331
function prepare ( options : unknown ) {
339
332
const entry = createListenerEntry (
333
+ // Fake out TS here
340
334
options as Parameters < AddListenerOverloads < unknown > > [ 0 ]
341
335
)
342
336
@@ -407,14 +401,6 @@ export function createActionListenerMiddleware<
407
401
D extends Dispatch < AnyAction > = ThunkDispatch < S , unknown , AnyAction > ,
408
402
ExtraArgument = unknown
409
403
> ( middlewareOptions : CreateListenerMiddlewareOptions < ExtraArgument > = { } ) {
410
- type ListenerEntry = ActionListenerOptions & {
411
- id : string
412
- listener : ActionListener < any , S , D >
413
- unsubscribe : ( ) = > void
414
- type ?: string
415
- predicate : ListenerPredicate < any , any >
416
- }
417
-
418
404
const listenerMap = new Map < string , ListenerEntry > ( )
419
405
const { extra , onError = defaultErrorHandler } = middlewareOptions
420
406
0 commit comments