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

React Redux TS高阶组件connect包装报ComponentType<never>类型错误

问题描述

实现ErrorBoundary高阶组件(HOC)时,尝试用react-redux的connect方法对其包装,抛出类型错误:typeof [a class] is not assignable to parameter of type 'ComponentType<never>',报错截图如下:
类型报错截图
已经按定义向HOC传入对应属性,但仍有报错,相关实现代码如下:

interface State {
  error: unknown;
  info: unknown;
}

interface WithErrorBoundaryProps {
  getNotification(...args: any): void;
}

const withErrorBoundary = <P extends WithErrorBoundaryProps>(
  TargetComponent: React.ComponentType<P>
) => {
  class ErrorBoundary extends React.PureComponent<P, State> {
    public state: State = {
      error: null,
      info: null,
    };

    public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
      getNotification({ alertType: 'error', message: error.message });
      this.setState({ error, info: errorInfo });
    }

    public render() {
      const { ...props } = this.props;
      if (this.state.error instanceof Error) {
        return <Alert type="error">{this.state.error?.message}</Alert>;
      }
      return <TargetComponent {...(props as P)} />;
    }
  }

  return ErrorBoundary;
};

export const connectedErrorBoundary = connect(null, {
  getNotification: getNotificationAction,
})(withErrorBoundary);
报错原因
  • 核心逻辑错误:connect方法的入参必须是一个合法的React组件(类组件/函数组件),但代码中直接把withErrorBoundary这个接收组件、返回新组件的HOC函数传给了connect,不符合组件类型要求。
  • 类型推断失败:由于传入的是HOC函数而非组件,TS无法推导HOC需要的泛型参数,默认将组件Props类型推断为never,最终抛出类型不匹配错误。
  • 隐性逻辑问题:componentDidCatch生命周期中直接调用getNotification,但该方法是需要connect注入到props中的,全局作用域下不存在该方法,运行时会报未定义错误。
修复方案
  1. 调整connect调用位置:不要在HOC外部包装HOC本身,改为在HOC内部对最终返回的ErrorBoundary类组件做connect包装,让redux把getNotification方法正确注入到组件props中。
  2. 修正方法调用逻辑:在componentDidCatch中从this.props读取注入的getNotification方法,不要直接调用全局未定义变量。
  3. 拆分类型定义:区分redux注入的Props、透传给目标组件的Props,避免泛型推断冲突。

修复后的完整代码:

import React, { ComponentType, PureComponent, ErrorInfo } from 'react';
import { connect } from 'react-redux';
import { Alert } from 'your-ui-library-path';
import { getNotification as getNotificationAction } from 'your-store-action-path';

// ErrorBoundary内部状态类型
interface ErrorBoundaryState {
  error: Error | null;
  info: ErrorInfo | null;
}

// redux connect注入的Props类型
interface InjectedProps {
  getNotification: (...args: any[]) => void;
}

const withErrorBoundary = <P extends object>(
  TargetComponent: ComponentType<P>
) => {
  // 内部ErrorBoundary组件Props = 透传给目标组件的Props + 注入的Props
  class ErrorBoundary extends PureComponent<P & InjectedProps, ErrorBoundaryState> {
    public state: ErrorBoundaryState = {
      error: null,
      info: null,
    };

    public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
      // 从props中读取注入的通知方法
      this.props.getNotification({ alertType: 'error', message: error.message });
      this.setState({ error, info: errorInfo });
    }

    public render() {
      // 拆分注入props和透传props,避免redux注入的属性被透传到目标组件
      const { getNotification, ...targetProps } = this.props;
      if (this.state.error) {
        return <Alert type="error">{this.state.error.message}</Alert>;
      }
      return <TargetComponent {...(targetProps as P)} />;
    }
  }

  // 在HOC内部connect包装ErrorBoundary组件
  const ConnectedErrorBoundary = connect(null, {
    getNotification: getNotificationAction,
  })(ErrorBoundary);

  return ConnectedErrorBoundary;
};

export default withErrorBoundary;

使用方式:

// 用HOC包裹业务组件即可,不需要手动传入getNotification,redux会自动注入
const YourBusinessComponent = (props: { id: string }) => {
  return <div>业务组件</div>
}

export default withErrorBoundary(YourBusinessComponent);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 10:39:32