TypeScript使用计算属性时该如何正确设置类型?
报错原因
TypeScript 不允许访问联合类型上非共有的属性,Person 独有的weight和Dog独有的mass不属于两种类型的公共属性,同时你没有将isDog的判断和player的类型做关联,TS无法自动推导两者的对应关系,因此抛出索引类型错误。
解决方案
方案1:内置类型收窄(最推荐,完全类型安全,无断言)
直接用in操作符判断属性是否存在,TS会自动完成类型收窄,不需要额外写类型守卫:
interface Person { name: string; weight: number; } interface Dog { name: string; mass: number } const player: Person | Dog = "Object with specific type" if ('mass' in player) { // 该分支TS自动识别player为Dog类型 if (player.mass === 0) return; } else { // 该分支TS自动识别player为Person类型 if (player.weight === 0) return; }
方案2:自定义类型守卫(适合判断逻辑复杂的场景)
如果你判断类型的逻辑不止依赖属性,可以封装自定义类型守卫,复用性更强:
// 你原本的isDog判断逻辑可以写到这个函数里 function isDogInstance(obj: Person | Dog): obj is Dog { // 也可以替换成你原本的判断逻辑,比如 return isDog; return 'mass' in obj; } if (isDogInstance(player)) { if (player.mass === 0) return; } else { if (player.weight === 0) return; }
方案3:动态属性安全断言(适合不想写分支的场景)
如果你确定isDog和属性的对应关系完全正确,可以用安全的类型断言跳过TS校验,不需要用到any:
const attribute = isDog ? 'mass' : 'weight'; // 断言为两种类型的交叉类型,保证属性一定存在 if ((player as Person & Dog)[attribute] === 0) return;
内容的提问来源于stack exchange,提问作者wantToBeAProgrammer
相关产品推荐
相关产品推荐

