I'm having trouble understanding why TypeScript is inferring a certain type for an array element when the type is a union type and the types 'overlap'. I've reduced it to this minimum repro:
interface Base {
id: string;
}
interface Child {
id: string;
parentId: string;
}
interface Obj {
nodes1: Base[] | Child[];
nodes2: (Base | Child)[];
}
const obj: Obj = {
nodes1: [],
nodes2: []
};
const node1 = obj.nodes1[0]; // typed as Base
const node2 = obj.nodes2[0]; // typed as Base | Child
If I change Base so it isn't just a subset of Child properties like this:
interface Base {
baseId: string;
}
Now, both node1 and node2 are inferred as Base | Child. This is what I'd expected the first time. In my real code, the array can either be all of type Base or all of type Child so the typing feels better as Base[] | Child[] but I've had to go with (Base | Child)[] for now. I could do a larger refactor to introduce generics but it's not a simple change.
Why is the type inferred as Base only and not Base | Child?