如何解决TS模板中访问联合类型对象属性时提示属性不存在的报错
报错原因
这个报错的本质是TypeScript联合类型默认只允许访问所有子类型共有的属性,balance仅在WithBalance类型中定义,不属于两个类型的共有属性,因此TS会抛出类型错误。
解决方案
方案1:运行时类型收窄(最安全)
通过in运算符判断属性是否存在,TS会自动识别这个判断完成类型收窄,不会再报错。如果是Angular框架模板可以这么写:
<span *ngIf="'balance' in object; else noBalance">{{ object.balance }}</span> <ng-template #noBalance>0</ng-template>
如果是其他框架/场景,也可以把判断逻辑封装到组件类的方法/getter中,模板直接调用即可:
// 组件类代码 get showBalance(): number { return 'balance' in this.object ? this.object.balance : 0 }
<!-- 模板代码 --> <span>{{ showBalance }}</span>
这个方案完全符合TypeScript类型规范,没有类型安全风险。
方案2:类型断言(适配原有写法)
如果你确定当前业务逻辑下这个属性访问不会出现异常,可以直接通过类型断言告诉TS该对象的类型:
<span>{{ (object as WithBalance)?.balance ?? 0 }}</span>
这个方案不用调整原有逻辑的结构,适合临时快速修复的场景。
方案3:调整联合类型定义
给WithoutBalance也加上balance的可选声明,值为undefined,让两个类型的属性集保持一致:
type WithBalance = { balance: number, name: string } type WithoutBalance = { balance?: undefined, name: string } // 调整后原来的模板写法可以直接正常使用
这个方案不用修改模板代码,适合可以调整类型定义的场景。
内容的提问来源于stack exchange,提问作者Sam Kazantsev
相关产品推荐
相关产品推荐

