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

如何在TypeScript中基于Props实现条件式接口与条件Props?

实现互斥Props的TypeScript方案

要实现传入time时禁止传入onPress(反之亦然)的约束,核心是利用TypeScript的联合类型+never类型定义互斥的Props集合,具体实现如下:

1. 拆分Props为互斥状态类型

将组件的两种状态(倒计时/可点击)拆分为独立类型,用never标记互斥属性,禁止非法传入:

// 公共属性:两种状态共享的字段
type CountdownButtonCommon = {
  t: (key: string) => string; // 替换原any,明确翻译函数类型
  title: string; // 替换原any,明确标题类型
};

// 倒计时状态:仅含time,禁止onPress
type CountdownState = CountdownButtonCommon & {
  time: number; // 倒计时秒数,替换原any
  onPress?: never; // 用never禁止传入该属性
};

// 可点击状态:仅含onPress,禁止time
type ClickableState = CountdownButtonCommon & {
  time?: never; // 用never禁止传入该属性
  onPress: () => void; // 点击回调,明确类型
};

// 最终Props类型:二选一的联合类型
type CountdownButtonProps = CountdownState | ClickableState;

2. 修改组件并处理类型收窄

将组件泛型参数改为上述联合类型,通过类型收窄让TypeScript正确推断当前状态的Props:

class CountDownButton extends Component<CountdownButtonProps> {
  render() {
    const { t, title } = this.props;

    // 通过'in'操作符收窄类型,判断当前为倒计时状态
    if ('time' in this.props) {
      const { time } = this.props;
      return (
        <View style={{ ...Layout.flexView }}>
          <Label text={t('common.countdown.otpCountdown')} style={{ ...LabelStyle.SubBodyText, color: Colors.black }} />
          <Label
            text={moment.utc(time * 1000).format('HH:mm:ss')}
            style={{ ...LabelStyle.SubBodyTextMedium, fontWeight: '500', color: Colors.black }}
          />
        </View>
      );
    } else {
      // TypeScript自动推断为可点击状态,onPress必然存在
      const { onPress } = this.props;
      return (
        <TouchableOpacity activeOpacity={1} style={styles.buttonContainer} onPress={onPress}>
          <Label text={title} style={{ ...LabelStyle.BodyTextMedium, color: Colors.white }} />
        </TouchableOpacity>
      );
    }
  }
}

效果说明

  • 传入time时若同时传onPress,TypeScript会直接报错(onPress被标记为never类型,无法赋值)
  • 未传入time时,必须传入onPress,否则TypeScript提示缺少必填属性
  • 替换原代码中的any类型,让类型检查更严格,避免潜在运行时错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:15:12