Accessing property of a union type in Angular template

Viewed 527

I have an union type item like the following:

export interface A {
  a: number
}

export interface B {
  b: string
}

export type MyUnionType = A | B;

I'd like to check in the template if an object of type MyUnionType is of type A or B based on the presence of the property a or b.

I expected something like this should work:

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

Here is a stackblitz

Any ideas? Thanks!

2 Answers

I use this way:

In ts:

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

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

in html:

<div>{{ getTypeA(item).a }}</div>
<div>{{ getTypeB(item).b }}</div>

The above approach will not work. When you define combined type like MyUnionType combining two or more types the resulting type expects all the properties present in child types also there should be one common property that exists in both of them.

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

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

export type MyUnionType = A | B;

Below snippet will work

    <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>

How to work with such types is very well documented here: https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html

Related