You need to enable JavaScript to run this app. TypeScript React props实现to/onClick二选一约束报错解决
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript React props实现to/onClick二选一约束报错解决

问题根因与修正方案

为什么会出现解构报错、约束失效

你遇到的问题本质是对TypeScript联合类型、交叉类型的规则存在两个认知偏差:

  • 联合类型的属性访问限制:TypeScript定义的联合类型A | B,代表变量的类型是「A的形状」或者「B的形状」,你只能直接访问A和B共同拥有的属性。如果直接访问仅存在于A或者仅存在于B的专属属性,TS就会抛出Property 'xxx' does not exist的错误。
    对应到你的代码中:LinkWithOnclickProps没有定义to属性,LinkWithToProps没有定义onClick属性,两个类型的共有属性只有公共LinkProps中定义的内容,因此直接从联合类型propsType上解构to、onClick时,TS无法确定你当前拿到的是哪一种类型,自然会报错。
  • 原定义未实现真正的二选一约束:你当前的类型写法实际允许用户同时传入to和onClick两个属性——因为同时携带两个属性的对象,既符合LinkWithToProps的结构要求,也符合LinkWithOnclickProps的结构要求,可以顺利通过类型检查,完全达不到「必须二选一、不能同时传、不能都不传」的核心目标。

具体修正步骤

1. 定义严格互斥的props联合类型

给两个变体类型显式标记对方的专属属性never类型,从根源上禁止属性同时传入的情况:

type LinkProps = {
  children: any;
  // ...其余公共属性
};

// 携带to的变体:必须传入to,禁止传入onClick
type LinkWithToProps = LinkProps & {
  to: string | { pathname: string };
  onClick?: never;
};

// 携带onClick的变体:必须传入onClick,禁止传入to
type LinkWithOnclickProps = LinkProps & {
  onClick: (params: any) => void;
  to?: never;
};

type propsType = LinkWithOnclickProps | LinkWithToProps;

修改后TS会自动拦截两类非法使用:

  • 两个属性都不传入:两个变体都要求必须携带其中一个核心属性,缺失就会直接抛出类型错误
  • 两个属性同时传入:每个变体都把对方的专属属性标记为never,传入不符合要求的属性就会触发类型校验错误

2. 组件内部通过类型收窄安全访问专属属性

因为to和onClick是两个联合变体的专属属性,不能直接从外层联合类型上解构,需要通过分支判断把类型收窄到具体的变体后,再读取对应属性:

const InternalLink = (props: propsType) => {
  // 通过in操作符完成类型收窄
  if ('to' in props) {
    // 进入该分支时,TS已经明确当前props是LinkWithToProps类型
    const { to, children } = props;
    // 此处可直接使用to完成跳转逻辑
    const href = typeof to === 'string' ? to : to.pathname;
    return <a href={href}>{children}</a>
  }

  // 走到此处时,剩余的唯一可能就是LinkWithOnclickProps类型
  const { onClick, children } = props;
  // 此处可直接使用onClick完成点击逻辑
  return <a onClick={onClick}>{children}</a>
}

注意:如果直接在组件最外层写const { to, onClick, children } = props,TS依然会抛出属性不存在的错误——此时还没有完成类型收窄,TS依然无法确定当前props对应的是哪一种变体,自然不允许直接访问非共有属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 09:06:00