如何在含联合类型的交叉类型上使用类型谓词访问属性
解决SelectedDetails类型访问Date属性的问题
你的SelectedDetails类型本质是(DetailsV1 & Selected) | (DetailsV2 & Selected),也就是两种交叉类型的联合,直接访问Date会报错——因为其中一个分支没有这个属性。可以通过以下两种方式安全访问:
方式一:复用现有类型守卫
你定义的detailsDTOIsV2可以直接用于SelectedDetails类型的对象,因为SelectedDetails是DetailsDTO和Selected的交叉类型,完全兼容DetailsDTO的结构。使用时通过类型守卫缩小范围即可:
const selectedItem: SelectedDetails = { ID: 1, Status: 0, Date: "2024-05-20" }; if (detailsDTOIsV2(selectedItem)) { // 这里TypeScript会推断selectedItem是DetailsV2 & Selected,可安全访问Date和ID console.log(selectedItem.Date); console.log(selectedItem.ID); } else { // 这里是DetailsV1 & Selected,无Date属性 console.log(selectedItem.Status); }
方式二:编写针对SelectedDetails的专属类型守卫
如果想更明确,也可以专门写一个适配SelectedDetails的类型守卫:
function selectedDetailsIsV2(details: SelectedDetails): details is DetailsV2 & Selected { return 'Date' in details && typeof details.Date === 'string'; } // 使用示例 const anotherItem: SelectedDetails = { ID: 2, Status: 1 }; if (selectedDetailsIsV2(anotherItem)) { console.log(anotherItem.Date); } else { console.log("该条目无日期信息"); }
原理说明
交叉类型与联合类型结合时,DetailsDTO & Selected会被TypeScript展开为(DetailsV1 & Selected) | (DetailsV2 & Selected)。只有通过类型守卫将对象缩小到DetailsV2 & Selected分支时,TypeScript才会确认Date属性存在,允许安全访问。
内容的提问来源于stack exchange,提问作者Krista P
相关产品推荐
相关产品推荐

