TypeScript Redux Dispatch类型错误:异步Action无法匹配Action类型
Redux异步Action类型错误修复方案
问题概述
所有dispatch异步Action时均触发类型错误,错误提示:
Argument of type '(dispatch: Dispatch) => Promise' is not assignable to parameter of type 'Action'
已尝试使用useAppDispatch但问题未解决。
相关代码重现
1. useEffect中的dispatch调用
useEffect(() => { dispatch(getTodos(findError)); }, []);
2. 异步Action函数getTodos
type Error = (err: null | string) => void export const getTodos = (findError: Error) => { return async (dispatch: Dispatch<Action>): Promise<Action> => { try { findError(null); const response = await axios(`...`); const result: TodoItem[] = response.data; return dispatch({ type: ActionTypes.GET_TODOS, payload: result, }); } catch (error) { findError("Ha ocurrido un error al cargar las tareas"); console.log(error); } }; };
3. Action类型定义
import { TodoItem } from "types/interfaces/interfaces.actions"; import { ActionTypes } from "redux/actions-types"; export interface GetTodos { type: ActionTypes.GET_TODOS; payload: TodoItem[]; } export interface DeleteTodo { type: ActionTypes.DELETE_TODO; payload: number | string; } export interface PutTodo{ type: ActionTypes.PUT_TODO, payload: PutTodoData } interface PutTodoData { id: number | string; checked: boolean; } export interface PostTodo{ type: ActionTypes.POST_TODO, payload: TodoItem } export interface OrderTodo{ type: ActionTypes.ORDER_TODO, payload: TodoItem[] } export type Action = GetTodos | DeleteTodo | PutTodo | PostTodo | OrderTodo;
修复步骤
1. 确认Redux Thunk中间件已配置
异步Action依赖Redux Thunk中间件,确保你的store已添加该中间件:
- 若使用
@reduxjs/toolkit,默认已包含Thunk,无需额外配置; - 若使用传统Redux,需手动安装并配置:
import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import rootReducer from './reducers'; export const store = createStore(rootReducer, applyMiddleware(thunk));
2. 定义支持Thunk的AppDispatch类型
在store配置文件中,导出包含Thunk支持的Dispatch类型:
// 若使用@reduxjs/toolkit import { configureStore } from '@reduxjs/toolkit'; import rootReducer from './reducers'; export const store = configureStore({ reducer: rootReducer, }); // 自动推导包含Thunk的Dispatch类型 export type AppDispatch = typeof store.dispatch; // 若使用传统Redux import { ThunkDispatch, Action } from 'redux'; import { RootState } from './reducers'; // 需导入你的RootState类型 export type AppDispatch = ThunkDispatch<RootState, unknown, Action>;
3. 自定义useAppDispatch Hook
在自定义hooks文件中,导出类型安全的dispatch hook:
import { useDispatch } from 'react-redux'; import type { AppDispatch } from '../store'; export const useAppDispatch = () => useDispatch<AppDispatch>();
4. 修正异步Action的类型定义
更新getTodos的返回类型为ThunkAction,确保类型匹配:
import { ThunkAction } from 'redux'; import { Action, ActionTypes } from './actions'; import { RootState } from './reducers'; // 导入RootState类型 type ErrorHandler = (err: null | string) => void; export const getTodos = (findError: ErrorHandler): ThunkAction<Promise<Action | void>, RootState, unknown, Action> => { return async (dispatch) => { try { findError(null); const response = await axios(`...`); const result: TodoItem[] = response.data; return dispatch({ type: ActionTypes.GET_TODOS, payload: result, }); } catch (error) { findError("Ha ocurrido un error al cargar las tareas"); console.log(error); } }; };
5. 在组件中使用自定义useAppDispatch
确保组件导入并使用自定义的useAppDispatch:
import { useAppDispatch } from '../hooks'; // ... const dispatch = useAppDispatch(); useEffect(() => { dispatch(getTodos(findError)); }, []);
原因说明
默认的Dispatch类型仅接受普通Action对象,而异步Action返回的是包含dispatch逻辑的函数(Thunk)。通过定义包含ThunkDispatch的AppDispatch类型,让TypeScript识别并支持异步Action的类型,从而解决类型不兼容问题。
内容的提问来源于stack exchange,提问作者Didier Brange
相关产品推荐
相关产品推荐

