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

咨询:使用discriminated union作为React类组件props类型时遇到的问题

咨询:使用discriminated union作为React类组件props类型时遇到的问题

嘿,我之前在开发React类组件的时候也碰到过这个联合类型props收窄的坑,咱们来聊聊怎么解决它~

首先先把你提到的最小示例代码整理出来方便参考:

type TypeAProps = {
  type: 'a';
  valueA: string;
};

type TypeBProps = {
  type: 'b';
  valueB: number;
};

type UnionProps = TypeAProps | TypeBProps;

class MyComponent extends React.Component<UnionProps> {
  render() {
    // 这里直接用this.props.type判断的话,TypeScript可能不会正确收窄类型
    if (this.props.type === 'a') {
      // 可能会报错:属性'valueA'在类型'UnionProps'上不存在
      return <div>{this.props.valueA}</div>;
    } else {
      // 同样可能报错属性'valueB'不存在
      return <div>{this.props.valueB}</div>;
    }
  }
}

这个问题的核心在于:React类组件的this.props是一个动态属性,TypeScript没办法很好地跟踪它的类型变化,哪怕你用判别式type做了判断,它还是会把this.props当成完整的联合类型。

给你几个实用的解决办法:

  • 解构props到局部变量
    把props解构出来或者赋值给一个局部变量,TypeScript就能正确识别类型收窄了:

    render() {
      const { type, valueA, valueB } = this.props;
      if (type === 'a') {
        return <div>{valueA}</div>;
      } else {
        return <div>{valueB}</div>;
      }
    }
    
  • 直接把this.props赋值给局部变量
    如果你不想解构,直接把this.props存到局部变量里也能解决:

    render() {
      const props = this.props;
      if (props.type === 'a') {
        return <div>{props.valueA}</div>;
      } else {
        return <div>{props.valueB}</div>;
      }
    }
    
  • 换成函数组件(更推荐)
    函数组件对联合类型的类型收窄支持得更自然,写法也更简洁,现在React官方也更推荐函数组件+hooks的写法:

    const MyComponent: React.FC<UnionProps> = (props) => {
      if (props.type === 'a') {
        return <div>{props.valueA}</div>;
      }
      return <div>{props.valueB}</div>;
    };
    

本质上就是让TypeScript能跟踪到一个固定的、不会动态变化的变量类型,而不是this.props这种可能在类生命周期中被更新的属性。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 13:34:39