@@ -68,10 +68,21 @@ function discriminated() {
6868 count ?: number
6969 }
7070
71+ interface MultiplyAction {
72+ type : 'MULTIPLY'
73+ count ?: number
74+ }
75+
76+ interface DivideAction {
77+ type : 'DIVIDE'
78+ count ?: number
79+ }
80+
7181 // Union of all actions in the app.
72- type MyAction = IncrementAction | DecrementAction
82+ type MyAction0 = IncrementAction | DecrementAction
83+ type MyAction1 = MultiplyAction | DivideAction
7384
74- const reducer : Reducer < State , MyAction > = ( state = 0 , action ) => {
85+ const reducer0 : Reducer < State , MyAction0 > = ( state = 0 , action ) => {
7586 if ( action . type === 'INCREMENT' ) {
7687 // Action shape is determined by `type` discriminator.
7788 // typings:expect-error
@@ -94,37 +105,65 @@ function discriminated() {
94105 return state
95106 }
96107
108+ const reducer1 : Reducer < State , MyAction1 > = ( state = 0 , action ) => {
109+ if ( action . type === 'MULTIPLY' ) {
110+ // typings:expect-error
111+ action . wrongField
112+
113+ const { count = 1 } = action
114+
115+ return state * count
116+ }
117+
118+ if ( action . type === 'DIVIDE' ) {
119+ // typings:expect-error
120+ action . wrongField
121+
122+ const { count = 1 } = action
123+
124+ return state / count
125+ }
126+
127+ return state
128+ }
129+
97130 // Reducer state is initialized by Redux using Init action which is private.
98131 // To initialize manually (e.g. in tests) we have to type cast init action
99132 // or add a custom init action to MyAction union.
100- let s : State = reducer ( undefined , { type : 'init' } as any )
101- s = reducer ( s , { type : 'INCREMENT' } )
102- s = reducer ( s , { type : 'INCREMENT' , count : 10 } )
133+ let s : State = reducer0 ( undefined , { type : 'init' } as any )
134+ s = reducer0 ( s , { type : 'INCREMENT' } )
135+ s = reducer0 ( s , { type : 'INCREMENT' , count : 10 } )
103136 // Known actions are strictly checked.
104137 // typings:expect-error
105- s = reducer ( s , { type : 'DECREMENT' , coun : 10 } )
106- s = reducer ( s , { type : 'DECREMENT' , count : 10 } )
138+ s = reducer0 ( s , { type : 'DECREMENT' , coun : 10 } )
139+ s = reducer0 ( s , { type : 'DECREMENT' , count : 10 } )
107140 // Unknown actions are rejected.
108141 // typings:expect-error
109- s = reducer ( s , { type : 'SOME_OTHER_TYPE' } )
142+ s = reducer0 ( s , { type : 'SOME_OTHER_TYPE' } )
110143 // typings:expect-error
111- s = reducer ( s , { type : 'SOME_OTHER_TYPE' , someField : 'value' } )
144+ s = reducer0 ( s , { type : 'SOME_OTHER_TYPE' , someField : 'value' } )
112145
113- // Combined reducer accepts any action by default which allows to include
114- // third-party reducers without the need to add their actions to the union.
115- const combined = combineReducers ( { sub : reducer } )
146+ // Combined reducer infers state and actions by default which maintains type
147+ // safety and still allows inclusion of third-party reducers without the need
148+ // to explicitly add their state and actions to the union.
149+ const combined = combineReducers ( { sub0 : reducer0 , sub1 : reducer1 } )
116150
117- let cs : { sub : State } = combined ( undefined , { type : 'init' } )
118- cs = combined ( cs , { type : 'SOME_OTHER_TYPE' } )
151+ const cs = combined ( undefined , { type : 'INCREMENT' } )
152+ combined ( cs , { type : 'MULTIPLY' } )
153+ // typings:expect-error
154+ combined ( cs , { type : 'init' } )
155+ // typings:expect-error
156+ combined ( cs , { type : 'SOME_OTHER_TYPE' } )
119157
120158 // Combined reducer can be made to only accept known actions.
121- const strictCombined = combineReducers < { sub : State } , MyAction > ( {
122- sub : reducer
159+ const strictCombined = combineReducers < { sub : State } , MyAction0 > ( {
160+ sub : reducer0
123161 } )
124162
125- strictCombined ( cs , { type : 'INCREMENT' } )
163+ const scs = strictCombined ( undefined , { type : 'INCREMENT' } )
164+ strictCombined ( scs , { type : 'DECREMENT' } )
126165 // typings:expect-error
127- strictCombined ( cs , { type : 'SOME_OTHER_TYPE' } )
166+ strictCombined ( scs , { type : 'SOME_OTHER_TYPE' } )
128167}
129168
130169/**
0 commit comments