You don’t want to be using useDispatch, useSelector etc directly in your code. Instead they are wrapped so that you can enjoy complete type safety!

TypeScript Hooks
import { configureStore } from "@reduxjs/toolkit";
import { useDispatch, useSelector } from "react-redux";
const store = configureStore({});
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export type RootState = ReturnType<typeof store.getState>;
export const useAppSelector = useSelector.withTypes<RootState>();
createAsyncThunk
import { Action, createAsyncThunk, ThunkAction } from "@reduxjs/toolkit";
export type AppThunk<ThunkReturnType = void> = ThunkAction<ThunkReturnType, RootState, unknown, Action>;
export const createAppAsyncThunk = createAsyncThunk.withTypes<{state: RootState, dispatch: AppDispatch}>();
// Complete example:
const createAppAsyncThunk = createAsyncThunk.withTypes<{
state: RootState
dispatch: AppDispatch
rejectValue: string
extra: { whatever: number }
}>()
createSelector
// Wrapping reselect createSelector
import { createSelector } from "@reduxjs/toolkit";
const createAppSelector = createSelector.withTypes<RootState>();
Also in this series
- Part 1: ReduxJS/Toolkit
- Part 2: ReduxJS/Toolkit: Immer
- Part 3: ReduxJS/Toolkit: createSlice and configureStore
- Part 4: ReduxJS/Toolkit: createAsyncThunk
- This Part: ReduxJS/Toolkit: TypeScript
- Part 6: ReduxJS/Toolkit: createSelector
Extras
Stuff that came into being during the making of this post