@@ -20,7 +20,11 @@ import type {
20
20
CurriedGetDefaultMiddleware ,
21
21
} from './getDefaultMiddleware'
22
22
import { curryGetDefaultMiddleware } from './getDefaultMiddleware'
23
- import type { NoInfer , ExtractDispatchExtensions } from './tsHelpers'
23
+ import type {
24
+ NoInfer ,
25
+ ExtractDispatchExtensions ,
26
+ ExtractStoreExtensions ,
27
+ } from './tsHelpers'
24
28
25
29
const IS_PRODUCTION = process . env . NODE_ENV === 'production'
26
30
@@ -29,9 +33,9 @@ const IS_PRODUCTION = process.env.NODE_ENV === 'production'
29
33
*
30
34
* @public
31
35
*/
32
- export type ConfigureEnhancersCallback = (
33
- defaultEnhancers : readonly StoreEnhancer [ ]
34
- ) => StoreEnhancer [ ]
36
+ export type ConfigureEnhancersCallback < E extends Enhancers = Enhancers > = (
37
+ defaultEnhancers : readonly StoreEnhancer [ ]
38
+ ) => [ ... E ]
35
39
36
40
/**
37
41
* Options for `configureStore()`.
@@ -41,7 +45,8 @@ export type ConfigureEnhancersCallback = (
41
45
export interface ConfigureStoreOptions <
42
46
S = any ,
43
47
A extends Action = AnyAction ,
44
- M extends Middlewares < S > = Middlewares < S >
48
+ M extends Middlewares < S > = Middlewares < S > ,
49
+ E extends Enhancers = Enhancers
45
50
> {
46
51
/**
47
52
* A single reducer function that will be used as the root reducer, or an
@@ -52,7 +57,7 @@ export interface ConfigureStoreOptions<
52
57
/**
53
58
* An array of Redux middleware to install. If not supplied, defaults to
54
59
* the set of middleware returned by `getDefaultMiddleware()`.
55
- *
60
+ *
56
61
* @example `middleware: (gDM) => gDM().concat(logger, apiMiddleware, yourCustomMiddleware)`
57
62
* @see https://redux-toolkit.js.org/api/getDefaultMiddleware#intended-usage
58
63
*/
@@ -79,7 +84,7 @@ export interface ConfigureStoreOptions<
79
84
- if it is not, there could be two cases:
80
85
- `ReducersMapObject<S, A>` is being passed in. In this case, we will call `combineReducers` on it and `CombinedState<S>` is correct
81
86
- `Reducer<S, A>` is being passed in. In this case, actually `CombinedState<S>` is wrong and `S` would be correct.
82
- As we cannot distinguish between those two cases without adding another generic paramter,
87
+ As we cannot distinguish between those two cases without adding another generic parameter,
83
88
we just make the pragmatic assumption that the latter almost never happens.
84
89
*/
85
90
preloadedState ?: PreloadedState < CombinedState < NoInfer < S > > >
@@ -92,21 +97,17 @@ export interface ConfigureStoreOptions<
92
97
* and should return a new array (such as `[applyMiddleware, offline]`).
93
98
* If you only need to add middleware, you can use the `middleware` parameter instead.
94
99
*/
95
- enhancers ?: StoreEnhancer [ ] | ConfigureEnhancersCallback
100
+ enhancers ?: E | ConfigureEnhancersCallback < E >
96
101
}
97
102
98
103
type Middlewares < S > = ReadonlyArray < Middleware < { } , S > >
99
104
100
- /**
101
- * A Redux store returned by `configureStore()`. Supports dispatching
102
- * side-effectful _thunks_ in addition to plain actions.
103
- *
104
- * @public
105
- */
106
- export interface EnhancedStore <
105
+ type Enhancers = ReadonlyArray < StoreEnhancer >
106
+
107
+ interface ToolkitStore <
107
108
S = any ,
108
109
A extends Action = AnyAction ,
109
- M extends Middlewares < S > = Middlewares < S >
110
+ M extends Middlewares < S > = Middlewares < S > ,
110
111
> extends Store < S , A > {
111
112
/**
112
113
* The `dispatch` method of your store, enhanced by all its middlewares.
@@ -116,19 +117,33 @@ export interface EnhancedStore<
116
117
dispatch : ExtractDispatchExtensions < M > & Dispatch < A >
117
118
}
118
119
120
+ /**
121
+ * A Redux store returned by `configureStore()`. Supports dispatching
122
+ * side-effectful _thunks_ in addition to plain actions.
123
+ *
124
+ * @public
125
+ */
126
+ export type EnhancedStore <
127
+ S = any ,
128
+ A extends Action = AnyAction ,
129
+ M extends Middlewares < S > = Middlewares < S > ,
130
+ E extends Enhancers = Enhancers
131
+ > = ToolkitStore < S , A , M > & ExtractStoreExtensions < E >
132
+
119
133
/**
120
134
* A friendly abstraction over the standard Redux `createStore()` function.
121
135
*
122
- * @param config The store configuration.
136
+ * @param options The store configuration.
123
137
* @returns A configured Redux store.
124
138
*
125
139
* @public
126
140
*/
127
141
export function configureStore <
128
142
S = any ,
129
143
A extends Action = AnyAction ,
130
- M extends Middlewares < S > = [ ThunkMiddlewareFor < S > ]
131
- > ( options : ConfigureStoreOptions < S , A , M > ) : EnhancedStore < S , A , M > {
144
+ M extends Middlewares < S > = [ ThunkMiddlewareFor < S > ] ,
145
+ E extends Enhancers = [ StoreEnhancer ]
146
+ > ( options : ConfigureStoreOptions < S , A , M , E > ) : EnhancedStore < S , A , M , E > {
132
147
const curriedGetDefaultMiddleware = curryGetDefaultMiddleware < S > ( )
133
148
134
149
const {
@@ -170,7 +185,7 @@ export function configureStore<
170
185
)
171
186
}
172
187
173
- const middlewareEnhancer = applyMiddleware ( ...finalMiddleware )
188
+ const middlewareEnhancer : StoreEnhancer = applyMiddleware ( ...finalMiddleware )
174
189
175
190
let finalCompose = compose
176
191
@@ -182,15 +197,15 @@ export function configureStore<
182
197
} )
183
198
}
184
199
185
- let storeEnhancers : StoreEnhancer [ ] = [ middlewareEnhancer ]
200
+ let storeEnhancers : Enhancers = [ middlewareEnhancer ]
186
201
187
202
if ( Array . isArray ( enhancers ) ) {
188
203
storeEnhancers = [ middlewareEnhancer , ...enhancers ]
189
204
} else if ( typeof enhancers === 'function' ) {
190
205
storeEnhancers = enhancers ( storeEnhancers )
191
206
}
192
207
193
- const composedEnhancer = finalCompose ( ...storeEnhancers ) as any
208
+ const composedEnhancer = finalCompose ( ...storeEnhancers ) as StoreEnhancer < any >
194
209
195
210
return createStore ( rootReducer , preloadedState , composedEnhancer )
196
211
}
0 commit comments