@@ -21,9 +21,10 @@ interface TypedActionCreator<Type extends string> {
21
21
match : MatchFunction < any >
22
22
}
23
23
24
- type ListenerPredicate < Action extends AnyAction , State = unknown > = (
24
+ type ListenerPredicate < Action extends AnyAction , State > = (
25
25
action : Action ,
26
- state ?: State
26
+ currentState ?: State ,
27
+ originalState ?: State
27
28
) => boolean
28
29
29
30
type MatchFunction < T > = ( v : any ) => v is T
@@ -38,6 +39,16 @@ export const hasMatchFunction = <T>(
38
39
return v && typeof ( v as HasMatchFunction < T > ) . match === 'function'
39
40
}
40
41
42
+ export const isActionCreator = (
43
+ item : Function
44
+ ) : item is TypedActionCreator < any > => {
45
+ return (
46
+ typeof item === 'function' &&
47
+ typeof ( item as any ) . type === 'string' &&
48
+ hasMatchFunction ( item as any )
49
+ )
50
+ }
51
+
41
52
/** @public */
42
53
export type Matcher < T > = HasMatchFunction < T > | MatchFunction < T >
43
54
@@ -208,7 +219,7 @@ const actualMiddlewarePhases = ['beforeReducer', 'afterReducer'] as const
208
219
* @alpha
209
220
*/
210
221
export function createActionListenerMiddleware <
211
- S ,
222
+ S = any ,
212
223
// TODO Carry through the thunk extra arg somehow?
213
224
D extends Dispatch < AnyAction > = ThunkDispatch < S , unknown , AnyAction > ,
214
225
ExtraArgument = unknown
@@ -218,7 +229,7 @@ export function createActionListenerMiddleware<
218
229
listener : ActionListener < any , S , D , any >
219
230
unsubscribe : ( ) => void
220
231
type ?: string
221
- predicate : ListenerPredicate < any >
232
+ predicate : ListenerPredicate < any , any >
222
233
}
223
234
224
235
const listenerMap = new Map < string , ListenerEntry > ( )
@@ -256,11 +267,12 @@ export function createActionListenerMiddleware<
256
267
const getOriginalState = ( ) => originalState
257
268
258
269
for ( const currentPhase of actualMiddlewarePhases ) {
259
- let stateNow = api . getState ( )
270
+ let currentState = api . getState ( )
260
271
for ( let entry of listenerMap . values ( ) ) {
261
272
const runThisPhase =
262
273
entry . when === 'both' || entry . when === currentPhase
263
- const runListener = runThisPhase && entry . predicate ( action , stateNow )
274
+ const runListener =
275
+ runThisPhase && entry . predicate ( action , currentState , originalState )
264
276
if ( ! runListener ) {
265
277
continue
266
278
}
@@ -306,30 +318,33 @@ export function createActionListenerMiddleware<
306
318
// eslint-disable-next-line no-redeclare
307
319
function addListener <
308
320
MA extends AnyAction ,
309
- M extends ListenerPredicate < MA > ,
321
+ M extends MatchFunction < MA > ,
310
322
O extends ActionListenerOptions
311
323
> (
312
324
matcher : M ,
313
- listener : ActionListener < AnyAction , S , D , O > ,
325
+ listener : ActionListener < GuardedType < M > , S , D , O > ,
314
326
options ?: O
315
327
) : Unsubscribe
316
328
// eslint-disable-next-line no-redeclare
317
329
function addListener <
318
330
MA extends AnyAction ,
319
- M extends MatchFunction < MA > ,
331
+ M extends ListenerPredicate < MA , S > ,
320
332
O extends ActionListenerOptions
321
333
> (
322
334
matcher : M ,
323
- listener : ActionListener < GuardedType < M > , S , D , O > ,
335
+ listener : ActionListener < AnyAction , S , D , O > ,
324
336
options ?: O
325
337
) : Unsubscribe
326
338
// eslint-disable-next-line no-redeclare
327
339
function addListener (
328
- typeOrActionCreator : string | TypedActionCreator < any > ,
340
+ typeOrActionCreator :
341
+ | string
342
+ | TypedActionCreator < any >
343
+ | ListenerPredicate < any , any > ,
329
344
listener : ActionListener < AnyAction , S , D , any > ,
330
345
options ?: ActionListenerOptions
331
346
) : Unsubscribe {
332
- let predicate : ListenerPredicate < any >
347
+ let predicate : ListenerPredicate < any , any >
333
348
let type : string | undefined
334
349
335
350
let entry = findListenerEntry (
@@ -340,11 +355,16 @@ export function createActionListenerMiddleware<
340
355
if ( typeof typeOrActionCreator === 'string' ) {
341
356
type = typeOrActionCreator
342
357
predicate = ( action : any ) => action . type === type
343
- } else if ( typeof typeOrActionCreator . type === 'string' ) {
344
- type = typeOrActionCreator . type
345
- predicate = typeOrActionCreator . match
346
358
} else {
347
- predicate = typeOrActionCreator as unknown as ListenerPredicate < any >
359
+ if ( isActionCreator ( typeOrActionCreator ) ) {
360
+ type = typeOrActionCreator . type
361
+ predicate = typeOrActionCreator . match
362
+ } else {
363
+ predicate = typeOrActionCreator as unknown as ListenerPredicate <
364
+ any ,
365
+ any
366
+ >
367
+ }
348
368
}
349
369
350
370
const id = nanoid ( )
0 commit comments