TypeScript+React中给同一prop传两种不同类型数组报错如何解决
问题原因
你将bodyData定义为Array<ListingsItems | OrderItems>联合类型数组后,TypeScript默认只允许访问两个接口共有的属性。你代码里直接访问的sale仅存在于OrderItems接口、itemNo仅存在于ListingsItems接口,TypeScript无法确定遍历到的单个元素属于哪个类型,因此抛出类型错误。
解决方案
方案1:用in操作符快速收窄类型(改造成本最低)
直接在访问属性前通过in操作符判断独有属性是否存在,TypeScript会自动识别当前元素的类型,修改报错代码即可:
<td className="obj-sale-body order-td-none"> {'sale' in obj ? obj.sale : obj.itemNo} </td> <td className="obj-sale-qty order-td-none"> {'qty' in obj ? obj.qty : obj.sell} </td>
适合临时解决、业务逻辑简单的场景。
方案2:封装类型谓词工具函数(更易维护)
先定义类型判断工具函数,后续多处用到类型判断时可以复用:
// 判断是否为订单项 const isOrderItem = (item: ListingsItems | OrderItems): item is OrderItems => { return 'sale' in item }
遍历使用时调用函数做判断:
<td className="obj-sale-body order-td-none"> {isOrderItem(obj) ? obj.sale : obj.itemNo} </td>
适合判断逻辑复杂、多处需要类型区分的场景。
方案3:将表格组件改为泛型组件(类型最安全,无运行时开销)
如果你的组件每次只会传入纯ListingsItems数组或者纯OrderItems数组,不会两种类型混传,用泛型组件是最优解:
// 组件props定义改为泛型 interface Props<T> { bodyData: T[]; headerData: any; // 可根据实际需求给headerData也做泛型定义 } // 组件声明改为泛型 const ListingsTable = <T extends ListingsItems | OrderItems>(props: Props<T>) => { // 组件内部原有逻辑 }
调用组件时TypeScript会自动根据传入的bodyData类型推导泛型,不需要额外做运行时类型判断,也不会有类型报错。
内容的提问来源于stack exchange,提问作者Mo1
相关产品推荐
相关产品推荐

