Angular模板中如何做类型检测 解决属性不存在及对象可能未定义报错
报错原因
Angular模板的类型检查严格遵循TypeScript语法规则,你的entry.resource是Bundle | Encounter联合类型,只有Bundle存在entry属性,模板内直接写entry.resource.entry的判断无法被TS识别为有效的类型窄化逻辑,因此抛出类型错误。
解决方案
方案1:使用$any()临时跳过类型检查(快速解决)
直接在模板中用Angular内置的$any()方法包裹变量,临时关闭该变量的类型检查,写法如下:
<ng-template *ngIf="$any(entry.resource).entry !== undefined"> <p-panel *ngFor="let resourceEntry of entry.resource?.entry" [header]="resourceEntry.resource.id" > ...
优点是改动最小,适合快速调试;缺点是失去了类型校验,不推荐长期使用。
方案2:组件内编写类型守卫(推荐,类型安全)
在对应的.ts组件文件中编写类型判断函数,用于窄化联合类型:
// 组件类中新增方法 isBundle(resource: Bundle | Encounter | undefined): resource is Bundle { return !!resource && 'entry' in resource; }
然后在模板中直接调用该方法做判断即可,TypeScript会自动识别类型守卫,完成类型窄化,后续访问entry属性不会报错:
<ng-template *ngIf="isBundle(entry.resource)"> <p-panel *ngFor="let resourceEntry of entry.resource.entry" [header]="resourceEntry.resource.id" > ...
该方案完全符合TS类型规范,保留了类型校验能力,是生产环境的最优选择。
方案3:递归渲染优化(针对嵌套Bundle场景)
如果你的Bundle结构嵌套层级不确定,可以配合ngTemplateOutlet实现递归渲染,避免重复写模板逻辑:
<!-- 定义可复用的Bundle渲染模板 --> <ng-template #bundleTemplate let-bundle="bundle"> <p-panel *ngFor="let resourceEntry of bundle.entry" [header]="resourceEntry.resource.id" > <!-- 如果子资源还是Bundle,递归调用当前模板 --> <ng-container *ngIf="isBundle(resourceEntry.resource)"> <ng-container *ngTemplateOutlet="bundleTemplate; context: {bundle: resourceEntry.resource}"></ng-container> </ng-container> <!-- 其他Encounter类型的渲染逻辑 --> <ng-container *ngIf="!isBundle(resourceEntry.resource)"> <!-- 渲染Encounter内容 --> </ng-container> </p-panel> </ng-template> <!-- 首次调用模板 --> <ng-container *ngIf="isBundle(entry.resource)"> <ng-container *ngTemplateOutlet="bundleTemplate; context: {bundle: entry.resource}"></ng-container> </ng-container>
内容的提问来源于stack exchange,提问作者Apollo
相关产品推荐
相关产品推荐

