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

TypeScript React项目集成redux-auth-wrapper:HOC包裹组件需手动传入注入props的类型错误求助

解决redux-auth-wrapper HOC包裹组件后的TypeScript类型错误

我明白你遇到的问题了——当你用redux-auth-wrapper的高阶组件(HOC)包裹组件后,直接用JSX语法<SubServiceOverview />渲染时,TypeScript会报错要求你传入HOC本该自动注入的props,比如redirect、isAuthenticated这些。而把组件传给Route的component属性时就没问题,这是因为Route的component属性会自动处理props传递,而直接渲染JSX时TypeScript会严格检查组件的props类型。

下面是具体的排查和解决方法:

原因分析

你的userIsAuthenticated HOC在类型定义上,把InjectedAuthRouterProps和组件自身的props合并后作为了包裹后组件的props类型,这就导致TypeScript认为你需要手动传入这些HOC本该注入的props。实际上,这些props是由HOC内部提供的,不需要外部传入。

解决方案

方案1:修正HOC的类型定义(推荐)

调整reduxAuth.ts中的makeUserIsAuthenticated函数的类型,确保包裹后的组件只需要接收自身的props,而HOC注入的props不会被要求外部传入:

// reduxAuth.ts
import { routerActions } from "connected-react-router";
import { AuthWrapperDecorator } from "redux-auth-wrapper";
import { connectedRouterRedirect, InjectedAuthRouterProps } from "redux-auth-wrapper/history4/redirect";
import { RootState } from "state/configureStore";
import { REDUCER_NAME } from "state/user/constants";

const authenticatedSelector = (state: RootState) => state[REDUCER_NAME] && state[REDUCER_NAME]["authenticated"];

// 修改返回类型:去掉 & InjectedAuthRouterProps,因为这些是HOC内部注入的,无需外部传入
export const makeUserIsAuthenticated = <OwnProps = Record<string, unknown>>(): AuthWrapperDecorator<OwnProps> => 
  connectedRouterRedirect<OwnProps, RootState>({
    redirectPath: "/login",
    authenticatedSelector,
    wrapperDisplayName: "UserIsAuthenticated",
    redirectAction: routerActions.replace
});

export const userIsAuthenticated = makeUserIsAuthenticated<Record<string, unknown>>();

然后,确保你的SubServiceOverview组件的props类型明确(如果没有自定义props,就用默认的{}):

// SubServiceOverview.tsx
import React from "react";
import { Link } from "react-router-dom";
import { userIsAuthenticated } from "libs/reduxAuth";
import services from "routes/services";

// 明确组件不需要外部传入props
const ServiceOverview: React.FC<{}> = () => {
  return (
    <div>
      <ul>
        {services.map(service => (
          <li key={service.name}>
            <Link to={`/services/${service.name}`}>{service.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default userIsAuthenticated(ServiceOverview);

这样修改后,TypeScript就不会再要求你传入HOC注入的props了,直接用<SubServiceOverview />渲染就正常了。

方案2:使用Route的render属性替代直接渲染JSX

如果你不想修改HOC的类型定义,也可以在Routes.tsx中使用Route的render属性来渲染组件,这样TypeScript不会严格检查组件的props:

// Routes.tsx
<Route path="/services/:subService" render={() => <SubServiceOverview />} />

这种方法简单快速,但属于绕过类型检查的临时方案,不如方案1规范。

方案3:明确组件的props类型(不推荐)

如果你想保留当前的HOC类型定义,可以让组件的props继承InjectedAuthRouterProps并标记这些props为可选,但这会让组件类型不够严谨,因为这些props本不该由外部传入:

// SubServiceOverview.tsx
import React from "react";
import { Link } from "react-router-dom";
import { userIsAuthenticated, InjectedAuthRouterProps } from "libs/reduxAuth";
import services from "routes/services";

// 标记HOC注入的props为可选
const ServiceOverview: React.FC<Partial<InjectedAuthRouterProps>> = () => {
  return (
    <div>
      <ul>
        {services.map(service => (
          <li key={service.name}>
            <Link to={`/services/${service.name}`}>{service.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default userIsAuthenticated(ServiceOverview);

验证

修改完成后重新编译项目,TypeScript的错误应该就会消失了。另外,Login组件没有报错是因为你把它传给了Route的component属性,Route会自动处理props传递,HOC也能正确注入需要的props。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:09:09