Blog>
Snippets

Applying Discriminated Unions in Action Types

Showcases the use of discriminated unions to create exhaustive checks on action types, ensuring that each case in the middleware is handled.
// Action Types
const FETCH_START = 'FETCH_START';
const FETCH_SUCCESS = 'FETCH_SUCCESS';
const FETCH_FAILURE = 'FETCH_FAILURE';

// Action Creators
const fetchStart = () => ({ type: FETCH_START });
const fetchSuccess = payload => ({ type: FETCH_SUCCESS, payload });
const fetchFailure = error => ({ type: FETCH_FAILURE, error });

// Discriminated Union for actions
type Action =
  | { type: typeof FETCH_START }
  | { type: typeof FETCH_SUCCESS, payload: any }
  | { type: typeof FETCH_FAILURE, error: Error };

// Reducer with exhaustive check
const reducer = (state = initialState, action: Action) => {
  switch (action.type) {
    case FETCH_START:
      // Handle start of fetching
      return { ...state, loading: true };
    case FETCH_SUCCESS:
      // Handle successful fetch
      return { ...state, loading: false, data: action.payload };
    case FETCH_FAILURE:
      // Handle fetch failure
      return { ...state, loading: false, error: action.error };
    default:
      // TypeScript now knows this must be impossible
      const _: never = action;
      return state;
  }
};
Defines a discriminated union type for Redux actions, providing a precise definition for each action. A reducer function is implemented which performs exhaustive checks using a switch statement over the action types.