Skip to content

Commit ac77814

Browse files
committed
Carry type of extra argument through the listener config
1 parent 793c5d5 commit ac77814

File tree

3 files changed

+40
-20
lines changed

3 files changed

+40
-20
lines changed

packages/action-listener-middleware/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ const defaultErrorHandler: ListenerErrorHandler = (...args: unknown[]) => {
273273
*/
274274
export function createActionListenerMiddleware<
275275
S = unknown,
276-
// TODO Carry through the thunk extra arg somehow?
277276
D extends Dispatch<AnyAction> = ThunkDispatch<S, unknown, AnyAction>,
278277
ExtraArgument = unknown
279278
>(middlewareOptions: CreateListenerMiddlewareOptions<ExtraArgument> = {}) {

packages/action-listener-middleware/src/tests/listenerMiddleware.test.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,21 +171,27 @@ describe('createActionListenerMiddleware', () => {
171171
describe('Middleware setup', () => {
172172
test('Allows passing an extra argument on middleware creation', () => {
173173
const originalExtra = 42
174-
middleware = createActionListenerMiddleware({
174+
const middleware = createActionListenerMiddleware({
175175
extra: originalExtra,
176176
})
177-
reducer = jest.fn(() => ({}))
178-
store = configureStore({
179-
reducer,
177+
const store = configureStore({
178+
reducer: counterSlice.reducer,
180179
middleware: (gDM) => gDM().prepend(middleware),
181180
})
182181

183182
let foundExtra = null
184183

185-
middleware.addListener({
184+
const typedAddListener = middleware.addListener as TypedAddListener<
185+
CounterState,
186+
typeof store.dispatch,
187+
typeof originalExtra
188+
>
189+
190+
typedAddListener({
186191
matcher: (action: AnyAction): action is AnyAction => true,
187192
listener: (action, listenerApi) => {
188193
foundExtra = listenerApi.extra
194+
expectType<typeof originalExtra>(listenerApi.extra)
189195
},
190196
})
191197

packages/action-listener-middleware/src/types.ts

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,11 @@ export interface ForkedTask<T> {
116116
/**
117117
* @alpha
118118
*/
119-
export interface ActionListenerMiddlewareAPI<S, D extends Dispatch<AnyAction>>
120-
extends MiddlewareAPI<D, S> {
119+
export interface ActionListenerMiddlewareAPI<
120+
S,
121+
D extends Dispatch<AnyAction>,
122+
ExtraArgument = unknown
123+
> extends MiddlewareAPI<D, S> {
121124
/**
122125
* Returns the store state as it existed when the action was originally dispatched, _before_ the reducers ran.
123126
*
@@ -171,7 +174,7 @@ export interface ActionListenerMiddlewareAPI<S, D extends Dispatch<AnyAction>>
171174
*/
172175
pause<M>(promise: Promise<M>): Promise<M>
173176
// TODO Figure out how to pass this through the other types correctly
174-
extra: unknown
177+
extra: ExtraArgument
175178
}
176179

177180
/**
@@ -180,8 +183,12 @@ export interface ActionListenerMiddlewareAPI<S, D extends Dispatch<AnyAction>>
180183
export type ActionListener<
181184
A extends AnyAction,
182185
S,
183-
D extends Dispatch<AnyAction>
184-
> = (action: A, api: ActionListenerMiddlewareAPI<S, D>) => void | Promise<void>
186+
D extends Dispatch<AnyAction>,
187+
ExtraArgument = unknown
188+
> = (
189+
action: A,
190+
api: ActionListenerMiddlewareAPI<S, D, ExtraArgument>
191+
) => void | Promise<void>
185192

186193
export interface ListenerErrorHandler {
187194
(error: unknown): void
@@ -261,7 +268,8 @@ export interface TakePattern<State> {
261268
export interface AddListenerOverloads<
262269
Return,
263270
S = unknown,
264-
D extends Dispatch = ThunkDispatch<S, unknown, AnyAction>
271+
D extends Dispatch = ThunkDispatch<S, unknown, AnyAction>,
272+
ExtraArgument = unknown
265273
> {
266274
/** Accepts a "listener predicate" that is also a TS type predicate for the action*/
267275
<MA extends AnyAction, LP extends ListenerPredicate<MA, S>>(
@@ -270,7 +278,12 @@ export interface AddListenerOverloads<
270278
type?: never
271279
matcher?: never
272280
predicate: LP
273-
listener: ActionListener<ListenerPredicateGuardedActionType<LP>, S, D>
281+
listener: ActionListener<
282+
ListenerPredicateGuardedActionType<LP>,
283+
S,
284+
D,
285+
ExtraArgument
286+
>
274287
} & ActionListenerOptions
275288
): Return
276289

@@ -281,7 +294,7 @@ export interface AddListenerOverloads<
281294
type?: never
282295
matcher?: never
283296
predicate?: never
284-
listener: ActionListener<ReturnType<C>, S, D>
297+
listener: ActionListener<ReturnType<C>, S, D, ExtraArgument>
285298
} & ActionListenerOptions
286299
): Return
287300

@@ -292,7 +305,7 @@ export interface AddListenerOverloads<
292305
type: T
293306
matcher?: never
294307
predicate?: never
295-
listener: ActionListener<Action<T>, S, D>
308+
listener: ActionListener<Action<T>, S, D, ExtraArgument>
296309
} & ActionListenerOptions
297310
): Return
298311

@@ -303,7 +316,7 @@ export interface AddListenerOverloads<
303316
type?: never
304317
matcher: M
305318
predicate?: never
306-
listener: ActionListener<GuardedType<M>, S, D>
319+
listener: ActionListener<GuardedType<M>, S, D, ExtraArgument>
307320
} & ActionListenerOptions
308321
): Return
309322

@@ -314,7 +327,7 @@ export interface AddListenerOverloads<
314327
type?: never
315328
matcher?: never
316329
predicate: LP
317-
listener: ActionListener<AnyAction, S, D>
330+
listener: ActionListener<AnyAction, S, D, ExtraArgument>
318331
} & ActionListenerOptions
319332
): Return
320333
}
@@ -340,10 +353,11 @@ export interface RemoveListenerAction<
340353
export type TypedAddListenerAction<
341354
S,
342355
D extends Dispatch<AnyAction> = ThunkDispatch<S, unknown, AnyAction>,
356+
ExtraArgument = unknown,
343357
Payload = ListenerEntry<S, D>,
344358
T extends string = 'actionListenerMiddleware/add'
345359
> = BaseActionCreator<Payload, T> &
346-
AddListenerOverloads<PayloadAction<Payload, T>, S, D>
360+
AddListenerOverloads<PayloadAction<Payload, T>, S, D, ExtraArgument>
347361

348362
/** A "pre-typed" version of `removeListenerAction`, so the listener args are well-typed */
349363
export type TypedRemoveListenerAction<
@@ -357,8 +371,9 @@ export type TypedRemoveListenerAction<
357371
/** A "pre-typed" version of `middleware.addListener`, so the listener args are well-typed */
358372
export type TypedAddListener<
359373
S,
360-
D extends Dispatch<AnyAction> = ThunkDispatch<S, unknown, AnyAction>
361-
> = AddListenerOverloads<Unsubscribe, S, D>
374+
D extends Dispatch<AnyAction> = ThunkDispatch<S, unknown, AnyAction>,
375+
ExtraArgument = unknown
376+
> = AddListenerOverloads<Unsubscribe, S, D, ExtraArgument>
362377

363378
/** A "pre-typed" version of `middleware.removeListener`, so the listener args are well-typed */
364379
export type TypedRemoveListener<

0 commit comments

Comments
 (0)