MCPcopy
hub / github.com/reduxjs/redux / typeGuards

Function typeGuards

test/typescript/reducers.ts:180–232  ·  view source on GitHub ↗

* Reducer definition using type guards.

()

Source from the content-addressed store, hash-verified

178 * Reducer definition using type guards.
179 */
180function typeGuards() {
181 function isAction<A extends Action>(action: Action, type: any): action is A {
182 return action.type === type
183 }
184
185 type State = number
186
187 interface IncrementAction {
188 type: 'INCREMENT'
189 count?: number
190 }
191
192 interface DecrementAction {
193 type: 'DECREMENT'
194 count?: number
195 }
196
197 const reducer: Reducer<State, AnyAction> = (state = 0, action) => {
198 if (isAction<IncrementAction>(action, 'INCREMENT')) {
199 // TODO: this doesn't seem to work correctly with UnknownAction - `action` becomes `UnknownAction & IncrementAction`
200 // Action shape is determined by the type guard returned from `isAction`
201 // @ts-expect-error
202 action.wrongField
203
204 const { count = 1 } = action
205
206 return state + count
207 }
208
209 if (isAction<DecrementAction>(action, 'DECREMENT')) {
210 // @ts-expect-error
211 action.wrongField
212
213 const { count = 1 } = action
214
215 return state - count
216 }
217
218 return state
219 }
220
221 let s: State = reducer(undefined, { type: 'init' })
222 s = reducer(s, { type: 'INCREMENT' })
223 s = reducer(s, { type: 'INCREMENT', count: 10 })
224 s = reducer(s, { type: 'DECREMENT' })
225 s = reducer(s, { type: 'DECREMENT', count: 10 })
226 s = reducer(s, { type: 'SOME_OTHER_TYPE', someField: 'value' })
227
228 const combined = combineReducers({ sub: reducer })
229
230 let cs: { sub: State } = combined(undefined, { type: 'init' })
231 cs = combined(cs, { type: 'INCREMENT', count: 10 })
232}
233
234/**
235 * Test ReducersMapObject with default type args.

Callers

nothing calls this directly

Calls 2

combineReducersFunction · 0.85
reducerFunction · 0.70

Tested by

no test coverage detected