I have a tree structure that contains Node<Item | Category>
type Item {
type: string; // DB discriminator that defaults to 'I'
id: string;
name: string;
text: string[];
}
type Category {
type: string; // DB discriminator that defaults to 'C'
id: string;
name: string;
sub: Category[];
}
interface Node<Item | Category> {
data: Item | Category;
}
Then there are 2 components CategoryAndItemTreeComponent
and ItemDetailsComponent
.
@Component({ selector: 'app-tree', ... })
export class CategoryAndItemTreeComponent ... {
selected?: Node<Item | Category> = null;
...
}
@Component({ selector: 'app-item', ... })
export class ItemDetailsComponent ... {
item?: Item;
...
}
I'd like to bind details field to selected field in html:
<app-tree #treeLink></app-tree>
<app-item [item]="treeLink.selected?.data"></app-item>
...but item
field is of type Item
, and treeLink.selected?.data
is an union of Item | Category
.
How do I check instance, cast and assign?
Is this not allowed in Angular or generally in TypeScript? Apparently this compiles (inside .ts file), but not in template.
this.item = <Item>selected;
CodePudding user response:
in order to add type casting inside the template, use a custom pipe that creates the cast for you
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customCast',
pure: true,
})
export class AsPipe implements PipeTransform {
transform<T, S extends T>(value: S): T {
return <T>value;
}
}
then you can use it in you template
treeLink.selected?.data | customCast Item