在 Angular 模板中访问联合类型的属性

Accessing property of a union type in Angular template

提问人:user2010955 提问时间:8/23/2020 最后编辑:user2010955 更新时间:11/17/2023 访问量:1062

问:

我有一个联合类型的项目,如下所示:

export interface A {
  a: number
}

export interface B {
  b: string
}

export type MyUnionType = A | B;

我想根据属性 a 或 b 的存在,检查 MyUnionType 类型的对象是否属于 A 或 B 类型。

我期望这样的事情应该有效:

<div *ngIf="'a' in item">
  {{item.a}}
</div>

这是一个堆栈闪电战

有什么想法吗?谢谢!

Angular 模板

评论


答:

0赞 Vishal 8/24/2020 #1

上述方法行不通。 当您定义组合类型(如 MyUnionType)组合两个或多个类型时,生成的类型需要子类型中存在的所有属性,并且它们中都应该存在一个公共属性。

 export interface A {
  a: number;
  c: string;
}

export interface B {
  b: string;
  c: string;
}

export type MyUnionType = A | B;

下面的代码片段将起作用

    <div>
      {{item.c}}
    </div>
// But below snippet will not work. Since TypeScript does not know which of the three
// potential types a could be.
// Trying to access a property which isn't shared
// across all types will raise an error
    <div>
       {{item.a}}
   </div>

如何使用此类类型在这里得到了很好的记录:https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html

评论

3赞 user2010955 8/24/2020
是的,但是使用 in 运算符,打字稿可以推断类型,因此在 if('a' in item) 中,项目不再是 A |B,但它只是A(typescriptlang.org/docs/handbook/...)。我也想在angular模板中使用相同的功能
3赞 msqar 6/16/2021
你设法解决了这个问题吗?我在自动取款机上遇到了同样的问题。
1赞 FierceDev 8/5/2021 #2

我是这样使用的:

在 ts 中:

getTypeA(item: A | B): A { 
  return (item as A);
}

getTypeB(item: A | B): B { 
  return (item as B);
}

在 HTML 中:

<div>{{ getTypeA(item).a }}</div>
<div>{{ getTypeB(item).b }}</div>
0赞 BoomShaka 11/17/2023 #3

类型谓词难道不是实现此目的的最佳方法吗? 请参阅此处的打字稿文档。

function isOfTypeA(something: any): something is A {
    return (
      typeof something === 'object' &&
      something !== null &&
      'a' in something
    );
}

然后在模板中,您可以执行以下操作:

<div *ngIf="isOfTypeA(item)">
    {{item.a}}
</div>

编译器不会抱怨,因为它知道您已经确定它确实属于 A 类型。