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

能否基于传入参数推断不同类型?TypeScript React组件实践

根据参数值推断不同类型的实现方案

你想要实现的是根据selectRange的布尔值,自动对应cb函数的参数类型,这个需求完全可以实现,问题出在React组件中解构参数时丢失了类型关联。

问题原因

你定义的FooProps是正确的联合类型,但当你解构{cb, selectRange}时,TypeScript会把这两个变量的类型拆解开:

  • cb被推断为((value: number) => void) | ((value: [number]) => void)
  • selectRange被推断为boolean

此时两者的类型关联被切断,TypeScript无法判断selectRange为true时,cb对应的是哪个函数类型,导致直接调用报错。

解决方案

方案1:保留props对象,不直接解构

通过直接访问props对象的属性,TypeScript可以通过props.selectRange的取值自动窄化整个props的类型分支,从而正确识别cb的参数类型:

import React from 'react';

type FooProps = {
  baseProp: string
} & ({
  cb: (value: number) => void;
  selectRange: false
} | {
  cb: (value: [number]) => void;
  selectRange: true
});

const FooComp: React.FC<FooProps> = (props) => {
  if (props.selectRange) {
    props.cb([1, 2]); // 类型匹配,无报错
  } else {
    props.cb(1); // 类型匹配,无报错
  }
  return <div>{props.baseProp}</div>;
};

方案2:解构后手动恢复类型关联(可选)

如果一定要解构参数,可以通过类型断言手动指定cb的类型,适合必须解构的场景:

const FooComp: React.FC<FooProps> = ({ cb, selectRange, baseProp }) => {
  if (selectRange) {
    (cb as (value: [number]) => void)([1, 2]);
  } else {
    (cb as (value: number) => void)(1);
  }
  return <div>{baseProp}</div>;
};

类型定义优化(可选)

你可以把联合类型拆分为更清晰的子类型,可读性更好,功能完全等价:

type FooBaseProps = { baseProp: string };

type FooSingleSelectProps = FooBaseProps & {
  cb: (value: number) => void;
  selectRange: false;
};

type FooRangeSelectProps = FooBaseProps & {
  cb: (value: [number]) => void;
  selectRange: true;
};

type FooProps = FooSingleSelectProps | FooRangeSelectProps;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:26:05