I have the following types
type ParentKeys = "mum" | "dad";
type ChildKeys = "alice" | "frank";
type Parents = {
[parentKey in ParentKeys]: {
children: {
[childKey in ChildKeys]: {
parent: parentKey;
key: childKey;
};
}[ChildKeys][];
};
};
That is, the inner child
objects { parent, key }
are mounted inside a tree structure, below their resp. parents; all parent-child
pairings are allowed. For an example check
const parents: Parents = {
mum: {
children: [
{ parent: "mum", key: "alice", },
],
},
dad: {
children: [
{ parent: "dad", key: "frank", },
{ parent: "dad", key: "alice", },
],
},
};
Now, if I'm using parents
inside an Angular template
<div *ngFor="let parent of parents | keyvalue">
<div *ngFor="let child of parent.value.children">
<div>child {{child.key}} of parent {{child.parent}}</div>
</div>
</div>
I get the error
Type
'(
{ parent: "mum"; key: "alice"; } |
{ parent: "mum"; key: "frank"; }
)[] |
(
{ parent: "dad"; key: "alice"; } |
{ parent: "dad"; key: "frank"; }
)[]'
is not assignable to type
'(
(
{ parent: "mum"; key: "alice"; } |
{ parent: "mum"; key: "frank"; }
)[] &
NgIterable<
{ parent: "mum"; key: "alice"; } |
{ parent: "mum"; key: "frank"; }
>
) | null | undefined'
.ngtsc(2322)
Of course this can be resolved using $any()
, but obviously something is wrong with my types, or with the KeyValuePipe
.
CodePudding user response:
simply change it like this
type Parents = {
[parentKey in ParentKeys]: {
children: Array<{
parent: ParentKeys;
key: ChildKeys;
}>;
};
};
CodePudding user response:
type Parents = {
[parentKey in ParentKeys]: {
children: {
parent: ParentKeys, key: ChildKeys
}[];
};
};
The issue was an over-complication in the typing of the children object.
The issue lies in own the keyvalue
pipe interacts with the *ngFor
.
The following html
works:
<div *ngFor="let parent of parents | keyvalue">
<div *ngFor="let child of parents[parent.key].children">
<div>child {{ child.key }} of parent {{ child.parent }}</div>
</div>
</div>
The main different is that instead of us calling parent.value
, we call parents[parent.key]
. Doing so means we obtain the value stored in the original object. This is because the keyvalue
combined with the *ngFor
modifies the object, causing it to lose its iterability and raising an error.