What You'll Learn
- How to set up and use Redux Toolkit and React-Redux with TypeScript
Welcome to the Redux Toolkit TypeScript Quick Start tutorial! This tutorial will briefly show how to use TypeScript with Redux Toolkit.
This page focuses on just how to set up the TypeScript aspects . For explanations of what Redux is, how it works, and full examples of how to use Redux Toolkit, see the tutorials linked in the "Tutorials Overview" page.
Redux Toolkit is already written in TypeScript, so its TS type definitions are built in.
React Redux has its type definitions in a separate
@types/react-redux typedefs package on NPM. In addition to typing the library functions, the types also export some helpers to make it easier to write typesafe interfaces between your Redux store and your React components.
As of React Redux v7.2.3, the
react-redux package has a dependency on
@types/react-redux, so the type definitions will be automatically installed with the library. Otherwise, you'll need to manually install them yourself (typically
npm install @types/react-redux ).
The Redux+TS template for Create-React-App comes with a working example of these patterns already configured.
Using configureStore should not need any additional typings. You will, however, want to extract the
RootState type and the
Dispatch type so that they can be referenced as needed. Inferring these types from the store itself means that they correctly update as you add more state slices or modify middleware settings.
Since those are types, it's safe to export them directly from your store setup file such as
app/store.ts and import them directly into other files.
While it's possible to import the
AppDispatch types into each component, it's better to create typed versions of the
useSelector hooks for usage in your application. This is important for a couple reasons:
useSelector, it saves you the need to type
(state: RootState)every time
useDispatch, the default
Dispatchtype does not know about thunks. In order to correctly dispatch thunks, you need to use the specific customized
AppDispatchtype from the store that includes the thunk middleware types, and use that with
useDispatch. Adding a pre-typed
useDispatchhook keeps you from forgetting to import
AppDispatchwhere it's needed.
Since these are actual variables, not types, it's important to define them in a separate file such as
app/hooks.ts, not the store setup file. This allows you to import them into any component file that needs to use the hooks, and avoids potential circular import dependency issues.
Each slice file should define a type for its initial state value, so that
createSlice can correctly infer the type of
state in each case reducer.
All generated actions should be defined using the
PayloadAction<T> type from Redux Toolkit, which takes the type of the
action.payload field as its generic argument.
You can safely import the
RootState type from the store file here. It's a circular import, but the TypeScript compiler can correctly handle that for types. This may be needed for use cases like writing selector functions.
The generated action creators will be correctly typed to accept a
payload argument based on the
PayloadAction<T> type you provided for the reducer. For example,
incrementByAmount requires a
number as its argument.
In some cases, TypeScript may unnecessarily tighten the type of the initial state. If that happens, you can work around it by casting the initial state using
as, instead of declaring the type of the variable:
In component files, import the pre-typed hooks instead of the standard hooks from React-Redux.
See the "Usage with TypeScript" page for extended details on how to use Redux Toolkit's APIs with TypeScript.