I'm having trouble filtering an array that's of a union type into a single type.
I've got code very similar to this example:
interface Section {
type: 'section';
name: string;
children: (Section | Link)[];
}
interface Link {
type: 'link';
title: string;
children: []
}
const json = JSON.stringify({
type: 'section',
name: 'Parent',
children: [
{ type: 'section', name: 's1', children: [] },
{ type: 'section', name: 's2', children: [{ type: 'section', name: 's2', children: [] }] },
{ type: 'link', title: 'l1', children: [] },
{ type: 'section', name: 's3', children: [] },
{ type: 'link', title: 'l2', children: [] },
]
});
let parentSection: Section | Link = JSON.parse(json);
const sections = parentSection.children.filter((item): item is Section => !!item && item.type === 'section');
JSON.stringify and JSON.parse are there so TS doesn't infer the type of parentSection from the data, which comes from an API in real world.
The problem is that the type of sections as inferred by TS is (Section | Link)[], but I'd expect it to be Section[] or Section[] | [].
What do I need to change here to make this work as I expect/want it to work? I can't affect the data itself, but I am the one writing types for it, so I change play with those. The Link items always come with the children array without any items in it.
I'd really appreciate some help. Thank you!