Blog>
Snippets

TypeScript Type Checking for Actions

Showcase how to use TypeScript to enforce type checking on Redux action creators to ensure that any changes to action types are caught at compile time.
// actionTypes.ts
// Define action type constants
export const INCREMENT_COUNTER = 'INCREMENT_COUNTER';
export const DECREMENT_COUNTER = 'DECREMENT_COUNTER';
Defines constants for action types to be used in action creators and reducers.
// actions.ts
import { INCREMENT_COUNTER, DECREMENT_COUNTER } from './actionTypes';

// Define Action types using TypeScript interfaces
interface IncrementAction {
  type: typeof INCREMENT_COUNTER;
}

interface DecrementAction {
  type: typeof DECREMENT_COUNTER;
}

// Union Action Type
export type CounterAction = IncrementAction | DecrementAction;

// Action creators with enforced return type
export function increment(): IncrementAction {
  return { type: INCREMENT_COUNTER };
}

export function decrement(): DecrementAction {
  return { type: DECREMENT_COUNTER };
}
Creates TypeScript interfaces for each action and defines the action creators with the enforced TypeScript return type.
// reducer.ts
import { CounterAction } from './actions';
import { INCREMENT_COUNTER, DECREMENT_COUNTER } from './actionTypes';

interface CounterState {
  value: number;
}

const initialState: CounterState = {
  value: 0
};

export function counterReducer(state: CounterState = initialState, action: CounterAction): CounterState {
  switch (action.type) {
    case INCREMENT_COUNTER:
      return { value: state.value + 1 };
    case DECREMENT_COUNTER:
      return { value: state.value - 1 };
    default:
      return state;
  }
}
Defines the Redux reducer using the CounterAction type for type-safe action handling, ensuring that only actions of the defined types are able to manipulate the state.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>TypeScript Redux Example</title>
</head>
<body>
  <div id="app">
    <!-- UI elements to display state and dispatch actions -->
    <button id="incrementButton">Increment</button>
    <button id="decrementButton">Decrement</button>
    <div id="counterValue">0</div>
  </div>

  <script src="path_to_compiled_bundle.js"></script>
</body>
</html>
The basic HTML structure for our application, including buttons that users will interact with to dispatch actions to increment or decrement the counter.
/* styles.css */
#app {
  text-align: center;
  margin-top: 50px;
}

button {
  margin: 5px;
  padding: 10px 15px;
}

#counterValue {
  font-size: 2em;
  margin-top: 20px;
}
Adds basic styling for the application to improve usability and aesthetics.