Skip to content

Commit e1256f3

Browse files
author
Anton Dalgren
committed
feat: Adds ExtraArgument to withTypes for listenerMiddleware.
These changes are based upon the changes in introduction of withTypes for the listenerMiddleware.
1 parent a9362fb commit e1256f3

File tree

4 files changed

+81
-43
lines changed

4 files changed

+81
-43
lines changed

docs/api/createListenerMiddleware.mdx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,11 +488,14 @@ To fix this, the middleware provides types for defining "pre-typed" versions of
488488
import { createListenerMiddleware, addListener } from '@reduxjs/toolkit'
489489
import type { RootState, AppDispatch } from './store'
490490

491+
declare type ExtraArgument = {foo: string};
492+
491493
export const listenerMiddleware = createListenerMiddleware()
492494

493495
export const startAppListening = listenerMiddleware.startListening.withTypes<
494496
RootState,
495-
AppDispatch
497+
AppDispatch,
498+
ExtraArgument
496499
>()
497500

498501
export const addAppListener = addListener.withTypes<RootState, AppDispatch>()

packages/toolkit/src/listenerMiddleware/tests/listenerMiddleware.withTypes.test-d.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ type AppThunk<ThunkReturnType = void> = ThunkAction<
6464
unknown,
6565
Action
6666
>
67+
type ExtraArgument = { foo: string }
6768

6869
describe('listenerMiddleware.withTypes<RootState, AppDispatch>()', () => {
6970
const listenerMiddleware = createListenerMiddleware()
@@ -77,11 +78,12 @@ describe('listenerMiddleware.withTypes<RootState, AppDispatch>()', () => {
7778
test('startListening.withTypes', () => {
7879
const startAppListening = listenerMiddleware.startListening.withTypes<
7980
RootState,
80-
AppDispatch
81+
AppDispatch,
82+
ExtraArgument
8183
>()
8284

8385
expectTypeOf(startAppListening).toEqualTypeOf<
84-
TypedStartListening<RootState, AppDispatch>
86+
TypedStartListening<RootState, AppDispatch, ExtraArgument>
8587
>()
8688

8789
startAppListening({
@@ -102,6 +104,8 @@ describe('listenerMiddleware.withTypes<RootState, AppDispatch>()', () => {
102104

103105
expectTypeOf(stateCurrent).toEqualTypeOf<RootState>()
104106

107+
expectTypeOf(listenerApi.extra).toEqualTypeOf<ExtraArgument>()
108+
105109
timeout = 1
106110
takeResult = await listenerApi.take(increment.match, timeout)
107111

@@ -111,10 +115,10 @@ describe('listenerMiddleware.withTypes<RootState, AppDispatch>()', () => {
111115
})
112116

113117
test('addListener.withTypes', () => {
114-
const addAppListener = addListener.withTypes<RootState, AppDispatch>()
118+
const addAppListener = addListener.withTypes<RootState, AppDispatch, ExtraArgument>()
115119

116120
expectTypeOf(addAppListener).toEqualTypeOf<
117-
TypedAddListener<RootState, AppDispatch>
121+
TypedAddListener<RootState, AppDispatch, ExtraArgument>
118122
>()
119123

120124
store.dispatch(
@@ -126,27 +130,30 @@ describe('listenerMiddleware.withTypes<RootState, AppDispatch>()', () => {
126130
expectTypeOf(state).toEqualTypeOf<RootState>()
127131

128132
expectTypeOf(listenerApi.dispatch).toEqualTypeOf<AppDispatch>()
133+
134+
expectTypeOf(listenerApi.extra).toEqualTypeOf<ExtraArgument>()
129135
},
130136
}),
131137
)
132138
})
133139

134140
test('removeListener.withTypes', () => {
135-
const removeAppListener = removeListener.withTypes<RootState, AppDispatch>()
141+
const removeAppListener = removeListener.withTypes<RootState, AppDispatch, ExtraArgument>()
136142

137143
expectTypeOf(removeAppListener).toEqualTypeOf<
138-
TypedRemoveListener<RootState, AppDispatch>
144+
TypedRemoveListener<RootState, AppDispatch, ExtraArgument>
139145
>()
140146
})
141147

142148
test('stopListening.withTypes', () => {
143149
const stopAppListening = listenerMiddleware.stopListening.withTypes<
144150
RootState,
145-
AppDispatch
151+
AppDispatch,
152+
ExtraArgument
146153
>()
147154

148155
expectTypeOf(stopAppListening).toEqualTypeOf<
149-
TypedStopListening<RootState, AppDispatch>
156+
TypedStopListening<RootState, AppDispatch, ExtraArgument>
150157
>()
151158
})
152159
})

packages/toolkit/src/listenerMiddleware/tests/listenerMiddleware.withTypes.test.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,25 @@ type AppThunk<ThunkReturnType = void> = ThunkAction<
5555
Action
5656
>
5757

58+
type ExtraArgument = { foo: string }
59+
5860
const listenerMiddleware = createListenerMiddleware()
5961

6062
const startAppListening = listenerMiddleware.startListening.withTypes<
6163
RootState,
62-
AppDispatch
64+
AppDispatch,
65+
ExtraArgument
6366
>()
6467

6568
const stopAppListening = listenerMiddleware.stopListening.withTypes<
6669
RootState,
67-
AppDispatch
70+
AppDispatch,
71+
ExtraArgument
6872
>()
6973

70-
const addAppListener = addListener.withTypes<RootState, AppDispatch>()
74+
const addAppListener = addListener.withTypes<RootState, AppDispatch, ExtraArgument>()
7175

72-
const removeAppListener = removeListener.withTypes<RootState, AppDispatch>()
76+
const removeAppListener = removeListener.withTypes<RootState, AppDispatch, ExtraArgument>()
7377

7478
describe('startAppListening.withTypes', () => {
7579
test('should return startListening', () => {

packages/toolkit/src/listenerMiddleware/types.ts

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -511,11 +511,12 @@ export type RemoveListenerOverloads<
511511
unknown,
512512
UnknownAction
513513
>,
514+
ExtraArgument = unknown,
514515
> = AddListenerOverloads<
515516
boolean,
516517
StateType,
517518
DispatchType,
518-
any,
519+
ExtraArgument,
519520
UnsubscribeListenerOptions
520521
>
521522

@@ -556,22 +557,23 @@ export type TypedAddListener<
556557
> & {
557558
/**
558559
* Creates a "pre-typed" version of `addListener`
559-
* where the `state` and `dispatch` types are predefined.
560+
* where the `state`, `dispatch` and `extra` types are predefined.
560561
*
561-
* This allows you to set the `state` and `dispatch` types once,
562+
* This allows you to set the `state`, `dispatch` and `extra` types once,
562563
* eliminating the need to specify them with every `addListener` call.
563564
*
564-
* @returns A pre-typed `addListener` with the state and dispatch types already defined.
565+
* @returns A pre-typed `addListener` with the state, dispatch and extra types already defined.
565566
*
566567
* @example
567568
* ```ts
568569
* import { addListener } from '@reduxjs/toolkit'
569570
*
570-
* export const addAppListener = addListener.withTypes<RootState, AppDispatch>()
571+
* export const addAppListener = addListener.withTypes<RootState, AppDispatch, ExtraArguments>()
571572
* ```
572573
*
573574
* @template OverrideStateType - The specific type of state the middleware listener operates on.
574575
* @template OverrideDispatchType - The specific type of the dispatch function.
576+
* @template OverrideExtraArgument - The specific type of the extra object.
575577
*
576578
* @since 2.1.0
577579
*/
@@ -581,8 +583,9 @@ export type TypedAddListener<
581583
OverrideStateType,
582584
unknown,
583585
UnknownAction
584-
>,
585-
>() => TypedAddListener<OverrideStateType, OverrideDispatchType>
586+
>,
587+
OverrideExtraArgument = unknown,
588+
>() => TypedAddListener<OverrideStateType, OverrideDispatchType, OverrideExtraArgument>
586589
}
587590

588591
/**
@@ -597,34 +600,41 @@ export type TypedRemoveListener<
597600
unknown,
598601
UnknownAction
599602
>,
603+
ExtraArgument = unknown,
600604
Payload = ListenerEntry<StateType, DispatchType>,
601605
T extends string = 'listenerMiddleware/remove',
602606
> = BaseActionCreator<Payload, T> &
603607
AddListenerOverloads<
604608
PayloadAction<Payload, T>,
605609
StateType,
606610
DispatchType,
607-
any,
611+
ExtraArgument,
608612
UnsubscribeListenerOptions
609613
> & {
610614
/**
611615
* Creates a "pre-typed" version of `removeListener`
612-
* where the `state` and `dispatch` types are predefined.
616+
* where the `state`, `dispatch` and `extra` types are predefined.
613617
*
614-
* This allows you to set the `state` and `dispatch` types once,
618+
* This allows you to set the `state`, `dispatch` and `extra` types once,
615619
* eliminating the need to specify them with every `removeListener` call.
616620
*
617-
* @returns A pre-typed `removeListener` with the state and dispatch types already defined.
621+
* @returns A pre-typed `removeListener` with the state, dispatch and extra
622+
* types already defined.
618623
*
619624
* @example
620625
* ```ts
621626
* import { removeListener } from '@reduxjs/toolkit'
622627
*
623-
* export const removeAppListener = removeListener.withTypes<RootState, AppDispatch>()
628+
* export const removeAppListener = removeListener.withTypes<
629+
* RootState,
630+
* AppDispatch,
631+
* ExtraArguments
632+
* >()
624633
* ```
625634
*
626635
* @template OverrideStateType - The specific type of state the middleware listener operates on.
627636
* @template OverrideDispatchType - The specific type of the dispatch function.
637+
* @template OverrideExtraArgument - The specific type of the extra object.
628638
*
629639
* @since 2.1.0
630640
*/
@@ -635,7 +645,8 @@ export type TypedRemoveListener<
635645
unknown,
636646
UnknownAction
637647
>,
638-
>() => TypedRemoveListener<OverrideStateType, OverrideDispatchType>
648+
OverrideExtraArgument = unknown,
649+
>() => TypedRemoveListener<OverrideStateType, OverrideDispatchType, OverrideExtraArgument>
639650
}
640651

641652
/**
@@ -660,13 +671,13 @@ export type TypedStartListening<
660671
/**
661672
* Creates a "pre-typed" version of
662673
* {@linkcode ListenerMiddlewareInstance.startListening startListening}
663-
* where the `state` and `dispatch` types are predefined.
674+
* where the `state`, `dispatch` and `extra` types are predefined.
664675
*
665-
* This allows you to set the `state` and `dispatch` types once,
676+
* This allows you to set the `state`, `dispatch` and `extra` types once,
666677
* eliminating the need to specify them with every
667678
* {@linkcode ListenerMiddlewareInstance.startListening startListening} call.
668679
*
669-
* @returns A pre-typed `startListening` with the state and dispatch types already defined.
680+
* @returns A pre-typed `startListening` with the state, dispatch and extra types already defined.
670681
*
671682
* @example
672683
* ```ts
@@ -676,12 +687,14 @@ export type TypedStartListening<
676687
*
677688
* export const startAppListening = listenerMiddleware.startListening.withTypes<
678689
* RootState,
679-
* AppDispatch
690+
* AppDispatch,
691+
* ExtraArguments
680692
* >()
681693
* ```
682694
*
683695
* @template OverrideStateType - The specific type of state the middleware listener operates on.
684696
* @template OverrideDispatchType - The specific type of the dispatch function.
697+
* @template OverrideExtraArgument - The specific type of the extra object.
685698
*
686699
* @since 2.1.0
687700
*/
@@ -692,7 +705,8 @@ export type TypedStartListening<
692705
unknown,
693706
UnknownAction
694707
>,
695-
>() => TypedStartListening<OverrideStateType, OverrideDispatchType>
708+
OverrideExtraArgument = unknown,
709+
>() => TypedStartListening<OverrideStateType, OverrideDispatchType, OverrideExtraArgument>
696710
}
697711

698712
/**
@@ -707,17 +721,18 @@ export type TypedStopListening<
707721
unknown,
708722
UnknownAction
709723
>,
710-
> = RemoveListenerOverloads<StateType, DispatchType> & {
724+
ExtraArgument = unknown,
725+
> = RemoveListenerOverloads<StateType, DispatchType, ExtraArgument> & {
711726
/**
712727
* Creates a "pre-typed" version of
713728
* {@linkcode ListenerMiddlewareInstance.stopListening stopListening}
714-
* where the `state` and `dispatch` types are predefined.
729+
* where the `state`, `dispatch` and `extra` types are predefined.
715730
*
716-
* This allows you to set the `state` and `dispatch` types once,
731+
* This allows you to set the `state`, `dispatch` and `extra` types once,
717732
* eliminating the need to specify them with every
718733
* {@linkcode ListenerMiddlewareInstance.stopListening stopListening} call.
719734
*
720-
* @returns A pre-typed `stopListening` with the state and dispatch types already defined.
735+
* @returns A pre-typed `stopListening` with the state, dispatch and extra types already defined.
721736
*
722737
* @example
723738
* ```ts
@@ -727,12 +742,14 @@ export type TypedStopListening<
727742
*
728743
* export const stopAppListening = listenerMiddleware.stopListening.withTypes<
729744
* RootState,
730-
* AppDispatch
745+
* AppDispatch,
746+
* ExtraArguments
731747
* >()
732748
* ```
733749
*
734750
* @template OverrideStateType - The specific type of state the middleware listener operates on.
735751
* @template OverrideDispatchType - The specific type of the dispatch function.
752+
* @template OverrideExtraArgument - The specific type of the extra object.
736753
*
737754
* @since 2.1.0
738755
*/
@@ -743,7 +760,8 @@ export type TypedStopListening<
743760
unknown,
744761
UnknownAction
745762
>,
746-
>() => TypedStopListening<OverrideStateType, OverrideDispatchType>
763+
OverrideExtraArgument = unknown,
764+
>() => TypedStopListening<OverrideStateType, OverrideDispatchType, OverrideExtraArgument>
747765
}
748766

749767
/**
@@ -758,32 +776,37 @@ export type TypedCreateListenerEntry<
758776
unknown,
759777
UnknownAction
760778
>,
779+
ExtraArgument = unknown,
761780
> = AddListenerOverloads<
762781
ListenerEntry<StateType, DispatchType>,
763782
StateType,
764-
DispatchType
783+
DispatchType,
784+
ExtraArgument
765785
> & {
766786
/**
767787
* Creates a "pre-typed" version of `createListenerEntry`
768-
* where the `state` and `dispatch` types are predefined.
788+
* where the `state`, `dispatch` and `extra` types are predefined.
769789
*
770-
* This allows you to set the `state` and `dispatch` types once, eliminating
790+
* This allows you to set the `state`, `dispatch` and `extra` types once, eliminating
771791
* the need to specify them with every `createListenerEntry` call.
772792
*
773-
* @returns A pre-typed `createListenerEntry` with the state and dispatch types already defined.
793+
* @returns A pre-typed `createListenerEntry` with the state, dispatch and extra
794+
* types already defined.
774795
*
775796
* @example
776797
* ```ts
777798
* import { createListenerEntry } from '@reduxjs/toolkit'
778799
*
779800
* export const createAppListenerEntry = createListenerEntry.withTypes<
780801
* RootState,
781-
* AppDispatch
802+
* AppDispatch,
803+
* ExtraArguments
782804
* >()
783805
* ```
784806
*
785807
* @template OverrideStateType - The specific type of state the middleware listener operates on.
786808
* @template OverrideDispatchType - The specific type of the dispatch function.
809+
* @template OverrideExtraArgument - The specific type of the extra object.
787810
*
788811
* @since 2.1.0
789812
*/
@@ -794,7 +817,8 @@ export type TypedCreateListenerEntry<
794817
unknown,
795818
UnknownAction
796819
>,
797-
>() => TypedStopListening<OverrideStateType, OverrideDispatchType>
820+
OverrideExtraArgument = unknown,
821+
>() => TypedStopListening<OverrideStateType, OverrideDispatchType, OverrideExtraArgument>
798822
}
799823

800824
/**

0 commit comments

Comments
 (0)