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
相关产品推荐
相关产品推荐

