2
2
import { Action , AnyAction } from './actions'
3
3
import { Reducer } from './reducers'
4
4
5
+ /**
6
+ * returns the most basic type that will not interfere with the existing type
7
+ *
8
+ * Note that for non-object stuff, this will mess with replaceReducer. The
9
+ * assumption is that root reducers that only return a basic type (string, number, null, symbol) probably won't
10
+ * be using replaceReducer anyways.
11
+ */
12
+ export type BaseType < S > = S extends { } ? { } : S
13
+
5
14
/**
6
15
* Internal "virtual" symbol used to make the `CombinedState` type unique.
7
16
*/
@@ -107,8 +116,15 @@ export type Observer<T> = {
107
116
*
108
117
* @template S The type of state held by this store.
109
118
* @template A the type of actions which may be dispatched by this store.
119
+ * @template StateExt any extension to state from store enhancers
120
+ * @template Ext any extensions to the store from store enhancers
110
121
*/
111
- export interface Store < S = any , A extends Action = AnyAction > {
122
+ export interface Store <
123
+ S = any ,
124
+ A extends Action = AnyAction ,
125
+ StateExt = BaseType < S > ,
126
+ Ext = { }
127
+ > {
112
128
/**
113
129
* Dispatches an action. It is the only way to trigger a state change.
114
130
*
@@ -179,9 +195,9 @@ export interface Store<S = any, A extends Action = AnyAction> {
179
195
*
180
196
* @param nextReducer The reducer for the store to use instead.
181
197
*/
182
- replaceReducer < NewState = S , NewActions extends A = A > (
198
+ replaceReducer < NewState , NewActions extends Action > (
183
199
nextReducer : Reducer < NewState , NewActions >
184
- ) : Store < NewState , NewActions >
200
+ ) : Store < NewState & StateExt , NewActions , StateExt , Ext > & Ext
185
201
186
202
/**
187
203
* Interoperability point for observable/reactive libraries.
@@ -204,15 +220,15 @@ export interface Store<S = any, A extends Action = AnyAction> {
204
220
* @template StateExt State extension that is mixed into the state type.
205
221
*/
206
222
export interface StoreCreator {
207
- < S , A extends Action , Ext , StateExt > (
223
+ < S , A extends Action , Ext = { } , StateExt = BaseType < S > > (
208
224
reducer : Reducer < S , A > ,
209
225
enhancer ?: StoreEnhancer < Ext , StateExt >
210
- ) : Store < S & StateExt , A > & Ext
211
- < S , A extends Action , Ext , StateExt > (
226
+ ) : Store < S & StateExt , A , StateExt , Ext > & Ext
227
+ < S , A extends Action , Ext = { } , StateExt = BaseType < S > > (
212
228
reducer : Reducer < S , A > ,
213
229
preloadedState ?: PreloadedState < S > ,
214
230
enhancer ?: StoreEnhancer < Ext >
215
- ) : Store < S & StateExt , A > & Ext
231
+ ) : Store < S & StateExt , A , StateExt , Ext > & Ext
216
232
}
217
233
218
234
/**
@@ -237,12 +253,12 @@ export interface StoreCreator {
237
253
* @template StateExt State extension that is mixed into the state type.
238
254
*/
239
255
export type StoreEnhancer < Ext = { } , StateExt = { } > = (
240
- next : StoreEnhancerStoreCreator
256
+ next : StoreEnhancerStoreCreator < Ext , StateExt >
241
257
) => StoreEnhancerStoreCreator < Ext , StateExt >
242
258
export type StoreEnhancerStoreCreator < Ext = { } , StateExt = { } > = <
243
259
S = any ,
244
260
A extends Action = AnyAction
245
261
> (
246
262
reducer : Reducer < S , A > ,
247
263
preloadedState ?: PreloadedState < S >
248
- ) => Store < S & StateExt , A > & Ext
264
+ ) => Store < S & StateExt , A , StateExt , Ext > & Ext
0 commit comments