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

TypeScript中如何定义React条件props以合法访问嵌套对象属性

问题原因

TypeScript 无法追踪可辨识联合类型中两个属性的关联关系:你定义的ConditionalProps虽然保证了type和iconName一定是匹配的,但解构为两个独立变量后,TS 只会把type识别为'solid' | 'outline'联合类型,iconName识别为所有合法图标名的联合类型,无法判定二者是一一对应的,因此认为索引访问存在非法风险。

解决方案

方案1:类型收窄(推荐,100%类型安全)

通过if分支判断type的值,TS 会自动收窄当前分支下iconName的合法范围,报错直接消除:

const App = ({type = "outline", iconName = "default"}: ConditionalProps) => {
  const text1 = icons[type];
  let text2: string;
  if (type === 'solid') {
    // 此分支下iconName自动被收窄为keyof typeof icons.solid
    text2 = icons.solid[iconName];
  } else {
    // 此分支下iconName自动被收窄为keyof typeof icons.outline
    text2 = icons.outline[iconName];
  }

  return (
    <div>
      <h1>选中的图标是...</h1>
      <h2>{Object.keys(text1)}</h2>
      <h2>{text2}</h2>
    </div>
  );
}

方案2:类型断言(适合逻辑简单、确认匹配关系一定合法的场景)

直接告诉 TS 你的iconName一定是当前type对应对象的合法键:

const text2 = icons[type][iconName as keyof typeof icons[typeof type]];

方案3:泛型改写组件(适合组件需要灵活扩展的场景)

从类型定义层面直接绑定type和iconName的关联关系,不需要额外的运行时代码:

const icons = {
  outline: {
    default: "x1",
    icon1: "icon1"
  },
  solid: {
    default: "x2",
    icon2: "icon2"
  }
} as const;

type IconType = keyof typeof icons;
type IconName<T extends IconType> = keyof typeof icons[T];

// 泛型props定义,自动绑定type和iconName的关系
type AppProps<T extends IconType> = {
  type?: T;
  iconName?: IconName<T>;
}

const App = <T extends IconType = 'outline'>({
  type = "outline" as T,
  iconName = "default" as IconName<T>
}: AppProps<T>) => {
  const text1 = icons[type];
  // 无任何类型报错
  const text2 = icons[type][iconName];

  return (
    <div>
      <h1>选中的图标是...</h1>
      <h2>{Object.keys(text1)}</h2>
      <h2>{text2}</h2>
    </div>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:24:02