I have an array with:
const list: Readonly<ListProps> = {some values}
interface ListProps {
type: 'radio' | 'check';
style: 'text' | 'button';
options: OptionProps[];
}
interface OptionProps {
label: string;
value: string;
sublist?: ListProps;
}
I filtered out options
to only leave those with sublist
:
const nodesWithSublist: ListNodeWithSublist[] = list.options.filter(
(style: OptionProps) => style.sublist,
);
interface ListNodeWithSublist {
label: string;
value: string;
sublist: ListProps;
}
I get error saying that OptionProps[]
can’t be assigned to ListNodeWithSublist[]
because sublist
can’t be undefined
. But since I filtered results to have only nodes with sublist
, I think it would be right to assign array to ListNodeWithSublist
. How to handle this?
This is, unfortunately, a limitation of TypeScript at the moment, see issue #42384, which is a suggestion for new behavior:
Typescript should be able to infer the type of an object, if a type guard was checked on a property of the said object. Currently, Typescript does correctly infer the type of the property, but not its parent object.
Until/unless that’s implemented, you can define your own type predicate instead:
function hasSublist(option: OptionProps): option is ListNodeWithSublist {
return typeof option.sublist !== "undefined";
}
…and then use it in that code (it also means you can leave off the type annotation, since it’s inferred from the result of the filter
):
const nodesWithSublist = list.options.filter(hasSublist);
This should answer your question: github.com/microsoft/TypeScript/issues/44866