DEV Community

Kay Gosho
Kay Gosho

Posted on • Edited on

useReducer in TypeScript, strictly typed version

https://reactjs.org/docs/hooks-reference.html#usereducer

interface Action<T extends string, P = undefined> { type: T payload: P } type Actions = | Action<'increment', { by: number }> | Action<'decrement', { by: number }> | Action<'reset', { to: number }> type Reducer<S, A extends Action<any, any>> = (s: S, a: A) => S const INITIAL_STATE = { count: 0, } as const const reducer: Reducer<typeof INITIAL_STATE, Actions>(state, action) => { switch (action.type) { case 'increment': return { count: state.count + action.payload.by }; case 'decrement': return { count: state.count - action.payload.by }; case 'reset': return { count: action.payload.to }; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} <button onClick={() => dispatch({ type: 'decrement', payload: { by: 1 })}>-</button>  <button onClick={() => dispatch({ type: 'increment', payload: { by: 1 }})}>+</button>  <button onClick={() => dispatch({ type: 'reset', payload: { to: 0 } })}>+</button>  </>  ); } 
Enter fullscreen mode Exit fullscreen mode

Top comments (4)

Collapse
 
mconnor profile image
mike connor

missing '=' before '(state, action) =>' ??

Collapse
 
acro5piano profile image
Kay Gosho

Thanks! I've fixed!

Collapse
 
waju profile image
Abolarin Olanrewaju Olabode

This is really cool.

Collapse
 
acro5piano profile image
Kay Gosho

Thanks!