You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Redux Thunk时TypeScript类型不兼容问题求助

TypeScript 结合 Redux Thunk 类型错误问题

我在使用 TypeScript 搭配 Redux Thunk 时遇到类型错误,报错信息如下:

Argument of type 'ThunkAction<void, EmptyObject & { items: ItemsState; }, unknown, AnyAction>' is not assignable to parameter of type 'AnyAction'

我已经按照官方文档的方式自定义了 Dispatch 函数,但问题依然存在。我知道有 Redux Toolkit 可以用,但不想使用它。

相关代码片段

1. Thunk Action 定义

export const fetchData =
  (): ThunkAction<void, RootState, unknown, AnyAction> => async (dispatch) => {
    dispatch({
      type: REQUEST,
    });
    try {
      const res = await axios.get(API_URL);
      dispatch({
        type: SUCCESS,
        payload: res.data,
      });
    } catch (error) {
      dispatch({
        type: FAILURE,
        payload: error,
      });
    }
  };

2. 组件中使用

import { useAppDispatch } from './hooks';

const dispatch = useAppDispatch();

useEffect(() => {
  dispatch(fetchData());
}, []);

3. 自定义 useAppDispatch

import { useDispatch } from 'react-redux';
import type { AppDispatch } from '../store';

type DispatchFunc = () => AppDispatch;
export const useAppDispatch: DispatchFunc = useDispatch;

4. Store 配置

import { applyMiddleware, compose, createStore } from 'redux';

import thunk from 'redux-thunk';
import rootReducer from '../reducers';

declare global {
  interface Window {
    __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
  }
}

const initialState = {};
const middleware = [thunk];

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(
  rootReducer,
  initialState,
  composeEnhancers(applyMiddleware(...middleware))
);

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

export default store;

5. TypeScript 配置

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "noEmit": true,
    "jsx": "react",
    "isolatedModules": true
  },
  "include": ["src"]
}

补充:另一个 Thunk 函数及 Actions

Thunk 函数

export const fetchData =
  (): ThunkAction<void, RootState, unknown, AnyAction> => async (dispatch) => {
    dispatch({
      type: actionTypes.FETCH_DATA,
    });
    try {
      const res = await axios.get(API_URL);
      dispatch(actions.loadSuccess(res.data));
    } catch (error) {
      dispatch(actions.loadError(error));
    }
  };

Actions.ts

const loadSuccess = (payload: TournamentType[]) => ({
  type: actionTypes.FETCH_SUCCESS,
  payload,
});

const loadError= (error: unknown) => ({
  type: actionTypes.FETCH_ERROR,
  payload: error,
});

我已经尝试重启 VS Code,但错误依然存在,请问该如何解决?


解决方案

问题出在 AppDispatch 的类型推导上:使用 createStore 搭配 thunk 中间件时,TypeScript 无法自动将 ThunkAction 的类型合并到默认的 Dispatch 类型中,导致自定义的 useAppDispatch 返回的类型依然只能处理普通 AnyAction,无法识别 Thunk。

修复步骤:

  1. 手动定义 AppDispatch 类型
    替换原来通过 typeof store.dispatch 推导的方式,显式指定包含 Thunk 的 Dispatch 类型:

    import { ThunkDispatch } from 'redux-thunk';
    import { AnyAction } from 'redux';
    
    // 替换原来的 AppDispatch 定义
    export type AppDispatch = ThunkDispatch<RootState, unknown, AnyAction>;
    
  2. 更新 Store 配置文件
    修改后的完整 Store 代码:

    import { applyMiddleware, compose, createStore } from 'redux';
    import { ThunkDispatch } from 'redux-thunk';
    import { AnyAction } from 'redux';
    
    import thunk from 'redux-thunk';
    import rootReducer from '../reducers';
    
    declare global {
      interface Window {
        __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
      }
    }
    
    const initialState = {};
    const middleware = [thunk];
    
    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    
    const store = createStore(
      rootReducer,
      initialState,
      composeEnhancers(applyMiddleware(...middleware))
    );
    
    export type RootState = ReturnType<typeof store.getState>;
    // 显式定义支持 Thunk 的 Dispatch 类型
    export type AppDispatch = ThunkDispatch<RootState, unknown, AnyAction>;
    
    export default store;
    
  3. 验证修复
    此时 useAppDispatch 返回的 dispatch 类型已经是 ThunkDispatch,可以正确接收 ThunkAction,类型错误会消失。

额外说明

如果你的 Thunk 需要传入自定义中间件参数(比如封装的 API 实例),可以调整 ThunkDispatch 的第二个泛型参数:

// 假设自定义参数类型为 ExtraArgs
type ExtraArgs = { api: AxiosInstance };
export type AppDispatch = ThunkDispatch<RootState, ExtraArgs, AnyAction>;

内容的提问来源于stack exchange,提问作者Ivelios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:04:55