TypeScript ensures state shape consistency across setters, reducers, and selectors. This lesson types local state, reducers, context values, and global stores.
Typing useState and useReducer
useState<User | null>(null) explicit generic when inference fails. useReducer<State, Action>(reducer, initialState) types both state and action union.
Define action types as discriminated union for exhaustive switch checking in reducers.
type State = { count: number };
type Action =
| { type: 'increment' }
| { type: 'add'; payload: number };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'increment': return { count: state.count + 1 };
case 'add': return { count: state.count + action.payload };
default: {
const _exhaustive: never = action;
return state;
}
}
}
never in default case ensures all actions handled — compile error if new action added.