You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular模板中使用交叉类型遇类型收窄问题求解决方案

解决Angular模板中交叉类型访问的问题

以下是几种无需拆分组件、避免重复类型检查的可行方案:

方案1:修改数组类型为元素联合类型+单次类型守卫

首先调整输入属性的类型,将数组的联合类型改为元素的联合类型,让模板能识别每个item的完整联合类型:

export class ExampleClassComponent {
  // 修改为元素级别的联合类型
  @Input() items: Array<InfoItem | InfoItemWithAction> = [];

  // 定义类型守卫函数
  isInfoItemWithAction(item: InfoItem | InfoItemWithAction): item is InfoItemWithAction {
    return 'action' in item && 'id' in item;
  }
}

模板中利用*ngIf的as语法,仅调用一次守卫就复用收窄后的变量:

<ul>
  <li *ngFor="let item of items">
    <div>
      {{ item.name }} {{ item.value }}
    </div>

    <ng-container *ngIf="isInfoItemWithAction(item) as actionItem">
      <button (click)="onActionClicked(actionItem)">
        <span [class.warn]="actionItem.action === 'delete'">
          {{ actionItem.action }}
        </span>
      </button>
    </ng-container>
  </li>
</ul>

方案2:直接在模板中进行类型收窄

无需额外定义守卫函数,直接在模板中用in操作符判断属性存在,配合as语法复用变量:

<ul>
  <li *ngFor="let item of items">
    <div>
      {{ item.name }} {{ item.value }}
    </div>

    <ng-container *ngIf="'action' in item && 'id' in item as actionItem">
      <button (click)="onActionClicked(actionItem)">
        <span [class.warn]="actionItem.action === 'delete'">
          {{ actionItem.action }}
        </span>
      </button>
    </ng-container>
  </li>
</ul>

方案3:临时绕过类型检查(不推荐长期使用)

如果只是临时调试或快速验证,可使用Angular模板的$any()函数跳过类型检查:

<ul>
  <li *ngFor="let item of items">
    <div>
      {{ item.name }} {{ item.value }}
    </div>

    <button *ngIf="$any(item).action" (click)="onActionClicked($any(item))">
      <span [class.warn]="$any(item).action === 'delete'">
        {{ $any(item).action }}
      </span>
    </button>
  </li>
</ul>

注意:此方法会丢失TypeScript的类型安全保障,仅适合临时场景。

内容的提问来源于stack exchange,提问作者Urastor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:57:25