Angular/ TypeScript - How to Type casting in HTML file?

Viewed 5358

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

3 Answers

One more solution. I use this for row template

  1. Create utility function
export function castTo<T>(): (row) => T {
  return (row) => row as T
}
  1. Call function in component
$row = castTo<YourType>();
  1. Use in template
$row(row).properties

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

Related