在 Angular 16 模板/类型推断中处理联合类型的最简洁方法?

问题描述 投票:0回答:1

我正在开发一个 Angular 16 项目,在该项目中我使用反应式声明方法。

经常,我必须处理发出不同类型数据的 Observables——要么是成功的数据,要么是错误的对象。两种返回类型都有其单独的接口。

我通常将它们定义为联合类型,但我发现在 Angular 模板中处理这些类型很麻烦。

这里有一个例子:

interface DataSuccess {
  value: string;
}

interface DataError {
  error: boolean;
  message: string;
}

type DataOrError = DataSuccess | DataError | null;

在我的组件中,我有一个这种联合类型的 Observable:

// COMPONENT
data$: Observable<DataOrError> = this.myService.getData();

在我的 Angular 模板中,我想根据 data$ 发出 DataSuccess 对象还是 DataError 对象来显示不同的内容。但是,这会导致 TypeScript 错误,指出 DataSuccess 类型上不存在错误,DataError 类型上不存在值。

// TEMPLATE
<div *ngIf="data$ | async as data">
  <!-- Throws TypeScript error -->
  <div *ngIf="data?.error">{{ data.message }}</div>
  <!-- Also throws TypeScript error -->
  <div *ngIf="!data?.error">{{ data.value }}</div>
</div>

在 Angular 中处理这种情况的最佳实践是什么? 有没有一种方法可以在 Angular 模板中执行类型检查而无需求助于类型安全性较低的方法(例如使用 $any() 类型转换函数)或将逻辑移至组件文件? 是否有任何我可能忽略的 Angular 功能或 TypeScript 功能可以简化此操作?

我在这里看到了几个类似的问题,但它们很旧,答案很少,而且答案并不令人满意。我想知道现在情况是否有所改变。

作为替代方案,我考虑使用统一的模型,即不是将两种不同的类型放入一个联合中,而是像这样:

interface DataResponse {
value?: object;
error?: boolean;
message:? string;
}

这将解决我的模板推断问题,但是,我会失去一些类型安全性。这是处理此问题的明智方法还是会为将来可能出现的问题打开大门?

angular typescript rxjs casting typeerror
1个回答
0
投票

您可以定义一个如下所示的枚举,而不是创建不同的接口来描述数据的状态:

enum DataStatus {
  Error = "Error",
  Success = "Success",
}

您现在可以在 html 模板中检查数据状态:

// TEMPLATE
<div *ngIf="data$ | async as data">
<ng-container *ngIf="data.status === DataStatus.Success">
  <div>{{ data.message }}</div>
  <div>{{ data.value }}</div>
  </ng-container>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.