@@ -190,7 +190,11 @@ interface InternalReducerHandlingContext<State> {
190
190
actionCreators : Record < string , any >
191
191
}
192
192
193
- export interface ReducerHandlingContext < State > {
193
+ export interface ReducerHandlingContext <
194
+ State ,
195
+ Name extends string ,
196
+ ReducerPath extends string ,
197
+ > {
194
198
/**
195
199
* Adds a case reducer to handle a single action type.
196
200
* @param actionCreator - Either a plain action type string, or an action creator generated by [`createAction`](./createAction) that can be used to determine the action type.
@@ -199,7 +203,7 @@ export interface ReducerHandlingContext<State> {
199
203
addCase < ActionCreator extends TypedActionCreator < string > > (
200
204
actionCreator : ActionCreator ,
201
205
reducer : CaseReducer < State , ReturnType < ActionCreator > > ,
202
- ) : ReducerHandlingContext < State >
206
+ ) : ReducerHandlingContext < State , Name , ReducerPath >
203
207
/**
204
208
* Adds a case reducer to handle a single action type.
205
209
* @param actionCreator - Either a plain action type string, or an action creator generated by [`createAction`](./createAction) that can be used to determine the action type.
@@ -208,7 +212,7 @@ export interface ReducerHandlingContext<State> {
208
212
addCase < Type extends string , A extends Action < Type > > (
209
213
type : Type ,
210
214
reducer : CaseReducer < State , A > ,
211
- ) : ReducerHandlingContext < State >
215
+ ) : ReducerHandlingContext < State , Name , ReducerPath >
212
216
213
217
/**
214
218
* Allows you to match incoming actions against your own filter function instead of only the `action.type` property.
@@ -224,7 +228,7 @@ export interface ReducerHandlingContext<State> {
224
228
addMatcher < A > (
225
229
matcher : TypeGuard < A > ,
226
230
reducer : CaseReducer < State , A extends Action ? A : A & Action > ,
227
- ) : ReducerHandlingContext < State >
231
+ ) : ReducerHandlingContext < State , Name , ReducerPath >
228
232
/**
229
233
* Add an action to be exposed under the final `slice.actions[reducerName]` key.
230
234
*
@@ -238,7 +242,10 @@ export interface ReducerHandlingContext<State> {
238
242
*
239
243
* dispatch(addPost(post))
240
244
*/
241
- exposeAction ( actionCreator : unknown ) : ReducerHandlingContext < State >
245
+ exposeAction (
246
+ actionCreator : unknown ,
247
+ ) : ReducerHandlingContext < State , Name , ReducerPath >
248
+
242
249
/**
243
250
* Add a case reducer to be exposed under the final `slice.caseReducers[reducerName]` key.
244
251
*
@@ -252,12 +259,34 @@ export interface ReducerHandlingContext<State> {
252
259
*
253
260
* slice.caseReducers.addPost([], addPost(post))
254
261
*/
255
- exposeCaseReducer ( reducer : unknown ) : ReducerHandlingContext < State >
262
+ exposeCaseReducer (
263
+ reducer : unknown ,
264
+ ) : ReducerHandlingContext < State , Name , ReducerPath >
265
+
256
266
/**
257
267
* Provides access to the initial state value given to the slice.
258
268
* If a lazy state initializer was provided, it will be called and a fresh value returned.
259
269
*/
260
270
getInitialState ( ) : State
271
+
272
+ /**
273
+ * The `name` option provided for the slice.
274
+ */
275
+ name : Name
276
+
277
+ /**
278
+ * The `reducerPath` option provided for the slice.
279
+ * Defaults to `name` if not provided.
280
+ */
281
+ reducerPath : ReducerPath
282
+
283
+ /**
284
+ * Tries to select the slice's state from a possible root state shape, using `reducerPath`.
285
+ * Throws an error if slice's state is not found.
286
+ *
287
+ * *Note that only the original `reducerPath` option is used - if a different `reducerPath` is used when injecting, this will not be reflected.*
288
+ */
289
+ selectSlice ( state : Record < ReducerPath , State > ) : State
261
290
}
262
291
263
292
export interface ReducerDetails {
@@ -314,10 +343,10 @@ export type ReducerCreator<Type extends RegisteredReducerType> = {
314
343
} & ( ReducerDefinitionsForType < Type > extends never
315
344
? { }
316
345
: {
317
- handle < State > (
346
+ handle < State , Name extends string , ReducerPath extends string > (
318
347
details : ReducerDetails ,
319
348
definition : ReducerDefinitionsForType < Type > ,
320
- context : ReducerHandlingContext < State > ,
349
+ context : ReducerHandlingContext < State , Name , ReducerPath > ,
321
350
) : void
322
351
} )
323
352
@@ -388,7 +417,7 @@ export interface Slice<
388
417
* Equivalent to `slice.getSelectors((state: RootState) => state[slice.reducerPath])`.
389
418
*/
390
419
get selectors ( ) : Id <
391
- SliceDefinedSelectors < State , Selectors , { [ K in ReducerPath ] : State } >
420
+ SliceDefinedSelectors < State , Selectors , Record < ReducerPath , State > >
392
421
>
393
422
394
423
/**
@@ -410,7 +439,7 @@ export interface Slice<
410
439
*
411
440
* Will throw an error if slice is not found.
412
441
*/
413
- selectSlice ( state : { [ K in ReducerPath ] : State } ) : State
442
+ selectSlice ( state : Record < ReducerPath , State > ) : State
414
443
}
415
444
416
445
/**
@@ -898,7 +927,7 @@ export function buildCreateSlice<
898
927
}
899
928
900
929
function getContext ( { reducerName } : ReducerDetails ) {
901
- const context : ReducerHandlingContext < State > = {
930
+ const context : ReducerHandlingContext < State , Name , ReducerPath > = {
902
931
addCase (
903
932
typeOrActionCreator : string | TypedActionCreator < any > ,
904
933
reducer : CaseReducer < State > ,
@@ -946,6 +975,17 @@ export function buildCreateSlice<
946
975
return context
947
976
} ,
948
977
getInitialState,
978
+ name,
979
+ reducerPath,
980
+ selectSlice ( state ) {
981
+ const sliceState = state [ reducerPath ]
982
+ if ( typeof sliceState === 'undefined' ) {
983
+ throw new Error (
984
+ `Could not find "${ name } " slice in state. In order for slice creators to use \`context.selectSlice\`, the slice must be nested in the state under its reducerPath: "${ reducerPath } "` ,
985
+ )
986
+ }
987
+ return sliceState
988
+ } ,
949
989
}
950
990
return context
951
991
}
0 commit comments