TypeScript中结构一致类型不同的对象如何联合?如何正确访问属性?
解决TypeScript中结构相似但类型不同对象的联合类型访问问题
你的问题核心在于当前的TEST接口没有建立action和params之间的类型关联——TypeScript不知道某个特定的action对应哪种params类型,所以直接访问params.name或params.badName会触发类型错误。
推荐方案:使用区分联合类型(Discriminated Unions)
区分联合类型是TypeScript处理这类关联联合场景的标准做法,它通过一个共同的"区分字段"(这里就是action),把不同的action和对应的params类型绑定在一起。
首先重构你的类型定义:
// 保留原有的用户类型 interface User { name: string | null, date: string | null } interface BadUser { badName: string | null, badDate: string | null } // 为每个action单独定义接口,绑定对应的params类型 interface ActionWithUser { action: 'action1', params: User } interface ActionWithBadUser { action: 'action2', params: BadUser } // 假设action3对应User类型,你可以根据实际需求调整 interface Action3 { action: 'action3', params: User } // 最终的联合类型 type TEST = ActionWithUser | ActionWithBadUser | Action3
如何安全访问属性
现在,当你使用TEST类型的变量时,TypeScript会根据action的值自动缩小params的类型范围,你可以通过switch或if判断来安全访问对应属性:
function processTest(test: TEST) { if (test.action === 'action1') { // 这里TypeScript明确知道test.params是User类型 console.log(test.params.name); console.log(test.params.date); } else if (test.action === 'action2') { // 这里test.params是BadUser类型 console.log(test.params.badName); console.log(test.params.badDate); } else { // 这里对应action3,params是User类型 console.log(test.params.name); } }
为什么原来的写法不行?
你原来的TEST接口中,action的联合类型和params的联合类型是完全独立的——TypeScript无法推断出action: 'action1'和params: User之间的关联,它只会认为params可能是User或BadUser中的任意一种,所以直接访问name或badName会被TypeScript阻止,避免潜在的运行时错误。
这种区分联合类型的写法不仅解决了类型访问的问题,还能让代码的可读性更强,其他开发者一眼就能看出每个action对应的参数结构。
内容的提问来源于stack exchange,提问作者etrix
相关产品推荐
相关产品推荐

