[SOLVED] Angular/ TypeScript – How to Type casting in HTML file?

Issue

I have a TypeScript interfaces:

export interface iA {
  name: string;
}
export interface iB {
  size: number;
}
export interface iX {
  id: number;
  data: iA | iB;
}

Then in one of my Angular component class I’m using interface iX:

// example.component.ts
class ExampleComplnent {
  public item: iX = {
    id: 1,
    data: { name: 'test' }
  }
}
<!-- example.component.html -->
<div>{{ item.data.name }}</div>

This will throw an error: Propery 'name' not exist on type 'iB'.

I know that in a TypeScript file I can use casting like this:

const name = (item.data as iA).name;

But how can I make casting on the HTML side?

I also want to mention that in my code I’m validating that item.data is of type iA, not of type iB. So I’m sure it have the property ‘name’.

Solution

Unfortunately that’s not possible. It depends on your implementation what the best solution is. You can use generics:

export interface iA {
  name: string;
}
export interface iB {
  size: number;
}
export interface iX<T extends (iA | iB)> {
  id: number;
  data: T;
}

export class ExampleComponent {
  item: iX<iA>;
}

You can use some method call from the template which asserts the type:

@Component({
  selector: 'my-app',
  template: '{{ getIaData(item)?.name }}',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  item: iX;

  getIaData(ix: iX): iA | undefined {
    return this.isIa(ix.data) ? ix.data : void 0; 
  }

  isIa(data: iA | iB): data is iA {
    return !!(data as iA).name;
  }
}

working example

and I’m sure there are more. But like I said, it depends on where you get the item from and how and where it is defined

Answered By – Poul Kruijt

Answer Checked By – Clifford M. (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *