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;
}
}
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
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.