@@ -10,6 +10,7 @@ import type {
10
10
CaseReducer ,
11
11
PayloadAction ,
12
12
PayloadActionCreator ,
13
+ ReducerCreators ,
13
14
SerializedError ,
14
15
SliceCaseReducers ,
15
16
ThunkDispatch ,
@@ -18,6 +19,7 @@ import type {
18
19
import { configureStore } from '@reduxjs/toolkit'
19
20
import { createAction , createSlice } from '@reduxjs/toolkit'
20
21
import { expectExactType , expectType , expectUnknown } from './helpers'
22
+ import { castDraft } from 'immer'
21
23
22
24
/*
23
25
* Test: Slice name is strongly typed.
@@ -559,6 +561,10 @@ const value = actionCreators.anyKey
559
561
expectType < string > ( nestedSelectors . selectToFixed ( nestedState ) )
560
562
}
561
563
564
+ /**
565
+ * Test: reducer callback
566
+ */
567
+
562
568
{
563
569
interface TestState {
564
570
foo : string
@@ -727,3 +733,57 @@ const value = actionCreators.anyKey
727
733
)
728
734
}
729
735
}
736
+
737
+ /** Test: wrapping createSlice should be possible, with callback */
738
+ {
739
+ interface GenericState < T > {
740
+ data ?: T
741
+ status : 'loading' | 'finished' | 'error'
742
+ }
743
+
744
+ const createGenericSlice = <
745
+ T ,
746
+ Reducers extends SliceCaseReducers < GenericState < T > >
747
+ > ( {
748
+ name = '' ,
749
+ initialState,
750
+ reducers,
751
+ } : {
752
+ name : string
753
+ initialState : GenericState < T >
754
+ reducers : ( create : ReducerCreators < GenericState < T > > ) => Reducers
755
+ } ) => {
756
+ return createSlice ( {
757
+ name,
758
+ initialState,
759
+ reducers : ( create ) => ( {
760
+ start : create . reducer ( ( state ) => {
761
+ state . status = 'loading'
762
+ } ) ,
763
+ success : create . reducer ( ( state , action : PayloadAction < T > ) => {
764
+ state . data = castDraft ( action . payload )
765
+ state . status = 'finished'
766
+ } ) ,
767
+ ...reducers ( create ) ,
768
+ } ) ,
769
+ } )
770
+ }
771
+
772
+ const wrappedSlice = createGenericSlice ( {
773
+ name : 'test' ,
774
+ initialState : { status : 'loading' } as GenericState < string > ,
775
+ reducers : ( create ) => ( {
776
+ magic : create . reducer ( ( state ) => {
777
+ expectType < GenericState < string > > ( state )
778
+ // @ts -expect-error
779
+ expectType < GenericState < number > > ( state )
780
+
781
+ state . status = 'finished'
782
+ state . data = 'hocus pocus'
783
+ } ) ,
784
+ } ) ,
785
+ } )
786
+
787
+ expectType < ActionCreatorWithPayload < string > > ( wrappedSlice . actions . success )
788
+ expectType < ActionCreatorWithoutPayload < string > > ( wrappedSlice . actions . magic )
789
+ }
0 commit comments