Migrating from AnyAction to Typed Actions in Redux

Showcase the process of replacing deprecated AnyAction with specific typed actions in a Redux action creator.
// Define action type constants

// Define typed action interfaces
interface IncrementAction {
    type: typeof INCREMENT;

interface DecrementAction {
    type: typeof DECREMENT;

// Combined type for actions
type CounterAction = IncrementAction | DecrementAction;

// Action creators returning typed actions
function increment(): IncrementAction {
    return { type: INCREMENT };

function decrement(): DecrementAction {
    return { type: DECREMENT };

// Example of using action creators
const incrementAction = increment();
const decrementAction = decrement();
This code snippet shows how to define typed actions and action creators in place of using the AnyAction type. Instead of using a general type for all actions, specific action interfaces for incrementing and decrementing are created. These interfaces are then used in action creators to return actions with these specific types. This helps in maintaining type safety within your Redux application, enabling clearer intent and better developer experience.
// Reducer using typed actions
function counterReducer(state = 0, action: CounterAction) {
    switch (action.type) {
        case INCREMENT:
            return state + 1;
        case DECREMENT:
            return state - 1;
            return state;
In this code snippet, we have a reducer that takes typed actions as its second parameter instead of AnyAction. The CounterAction type enables the TypeScript compiler to validate that the reducer is handling actions of the correct types and provides autocompletion and type checking within the switch-case statements. This typed reducer ensures that only valid actions can be dispatched to this reducer, which improves code maintainability and reduces the likelihood of runtime errors.