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

Redux Toolkit中间件结合react-redux连接器报错求助

Redux迁移至@reduxjs/toolkit后添加中间件触发TypeScript类型错误

问题背景

将Redux迁移到@reduxjs/toolkit后,未使用Toolkit中间件时功能正常,但添加中间件后组件出现TypeScript类型错误。

组件代码

import React from 'react';
import type { PayloadAction } from '@reduxjs/toolkit';

import { type AppDispatch, appConnect } from '@/store/app';
import { authActions } from '@/store/reducers/auth';

import HeaderView from './Header.view';

interface IPropsFromDispatch {
    logout: () => PayloadAction;
}

interface IProps extends IPropsFromDispatch {}

const Header: React.FC<IProps> = (props: React.PropsWithChildren<IProps>) => {
    const onExitButton = () => {
        props.logout();
    };

    return <HeaderView onExitButton={onExitButton} />;
};

Header.displayName = 'Header';
Header.defaultProps = {};

const mapDispatchToProps = (dispatch: AppDispatch): IPropsFromDispatch => {
    return {
        logout: (): PayloadAction => dispatch(authActions.logout()),
    };
};

export default appConnect(null, mapDispatchToProps)(React.memo(Header));

Store代码

import { configureStore } from '@reduxjs/toolkit';
import { type Connect, connect } from 'react-redux';

import authReducer from './reducers/auth';
import authListenMiddleware from './middlewares/auth';

const store = configureStore({
    reducer: {
        auth: authReducer,
    },
    middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(authListenMiddleware.middleware),
    devTools: process.env.REACT_APP_NODE_ENV === 'development',
});

export type AppState = ReturnType<typeof store.getState>;

export type AppDispatch = typeof store.dispatch;

export const appConnect = connect as Connect<AppState>;

export default store;

报错信息

TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type '(dispatch: AppDispatch) => IPropsFromDispatch' is not assignable to parameter of type 'MapDispatchToPropsParam<IPropsFromDispatch, {}>'.
      Type '(dispatch: AppDispatch) => IPropsFromDispatch' is not assignable to type 'MapDispatchToPropsFactory<IPropsFromDispatch, {}>'.
        Types of parameters 'dispatch' and 'dispatch' are incompatible.
          Type 'Dispatch<Action<unknown>>' is not assignable to type 'ThunkDispatch<{ auth: IAuthState; }, undefined, AnyAction> & ((action: Action<"listenerMiddleware/add") => UnsubscribeListener) & Dispatch<...>'.
            Type 'Dispatch<Action<unknown>>' is not assignable to type '(action: Action<"listenerMiddleware/add") => UnsubscribeListener'.
              Type 'Action<"listenerMiddleware/add">' is not assignable to type 'UnsubscribeListener'.
                Type 'Action<"listenerMiddleware/add">' provides no match for the signature '(unsubscribeOptions?: UnsubscribeListenerOptions | undefined): void'.

已尝试方案

曾参考相关GitHub Issue,但问题未解决。


解决方案

问题出在appConnect的类型定义上,仅指定AppState但未正确关联AppDispatch类型,导致mapDispatchToProps中的dispatch参数类型不匹配。

  1. 修改Store中的appConnect定义,同时关联State和Dispatch类型:
import { type Connect, connect } from 'react-redux';

// ... 其他代码 ...

export type AppDispatch = typeof store.dispatch;

// 正确定义appConnect的完整类型
export const appConnect = connect as Connect<AppState, {}, {}, AppDispatch>;
  1. 简化组件中IPropsFromDispatch的类型定义(组件无需使用dispatch返回的action对象):
interface IPropsFromDispatch {
    logout: () => void;
}

修改完成后,TypeScript类型错误即可解决。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:48:19