TypeScript:接口联合类型使用疑问:为何无法访问title属性?
问题描述
定义接口的options类型如下:
options: Array<{ title?: string; options: Option[]; }> | Option[];
使用map遍历数组时:
{options.map((option) => ( <SelectPrimitive.Group key={option.title}> {/* 内容 */} </SelectPrimitive.Group> ))}
尝试访问option.title时,TypeScript提示该属性不存在;但移除联合类型的第二部分(仅保留分组对象数组类型)后就能正常访问。请问为何会出现这种情况?
问题原因与解决方案
原因
你的options是两种数组的联合类型:一种是包含分组对象的数组(每个元素带可选title和options数组),另一种是普通Option元素的数组。当调用map遍历时,TypeScript会把回调参数option推断为分组对象 | Option的联合类型。
因为Option类型没有title属性,TypeScript无法确保当前遍历到的元素一定拥有title,所以会报错提示属性不存在。而当你移除Option[]分支后,options的类型被确定为分组对象数组,option的类型明确,自然能正常访问title。
解决方案
需要通过类型守卫缩小option的类型范围,让TypeScript明确当前元素的类型,示例如下:
{options.map((option, idx) => { // 通过in操作符判断是否存在title属性,缩小类型范围 if ('title' in option) { // 此处TypeScript自动推断option为分组对象类型 return <SelectPrimitive.Group key={option.title ?? idx}> {/* 分组内容 */} </SelectPrimitive.Group>; } else { // 此处TypeScript自动推断option为普通Option类型 return <SelectPrimitive.Option key={option.value}> {/* 单个选项内容 */} </SelectPrimitive.Option>; } })}
你也可以根据Option类型的独有特征(比如固定存在value属性)来做类型判断,只要能让TypeScript区分两种类型即可。
内容的提问来源于stack exchange,提问作者sir-haver
相关产品推荐
相关产品推荐

