Typescript: incompatible discriminating union
Answered
Large oak-apple gall posted this in #help-forum
Large oak-apple gallOP
I made simplified version of real code to showcase my error.
Problem: need to somehow allow both ImageType and VideoType to be used in component props. They have different shape of children items, thus they are distinct types
Data is coming from external source, I cannot modify its type. I can modify props of component
Error:
Problem: need to somehow allow both ImageType and VideoType to be used in component props. They have different shape of children items, thus they are distinct types
Data is coming from external source, I cannot modify its type. I can modify props of component
interface Data {
itemsType: "image" | "video";
items: {
id: string;
url?: string;
}[];
}
type Props = ImageType | VideoType;
type ImageType = {
itemsType: "image";
items: {
id: string;
url: string;
}[];
};
type VideoType = {
itemsType: "video";
items: {
id: string;
}[];
};
function component(props: Props) {
console.log(props);
}
const data: Data = {
itemsType: "video",
items: [{ id: "1" }],
};
component({
itemsType: data.itemsType,
items: data.items,
});
Error:
Argument of type '{ itemsType: "image" | "video"; items: { id: string; url?: string; }[]; }' is not assignable to parameter of type 'Props'.
Type '{ itemsType: "image" | "video"; items: { id: string; url?: string; }[]; }' is not assignable to type 'VideoType'.
Types of property 'itemsType' are incompatible.
Type '"image" | "video"' is not assignable to type '"video"'.
Type '"image"' is not assignable to type '"video"'.
Answered by joulev
the problem here is that
is valid
note here that you might want to check for the case of
too, it satisfies
{
itemsType: "image";
items: {
id: string;
}[];
}
is valid
Data
but not valid Props
, that's why there is the ts error. this cannot be fixed in the type level alone, you need to check during runtime toonote here that you might want to check for the case of
{
itemsType: "video";
items: {
id: string;
url: string;
}[];
}
too, it satisfies
VideoType
but having the url
might not necessarily be what you want.4 Replies
hmm so you can only change the types
Props
, ImageType
and VideoType
? you cannot change the Data
type?the problem here is that
is valid
note here that you might want to check for the case of
too, it satisfies
{
itemsType: "image";
items: {
id: string;
}[];
}
is valid
Data
but not valid Props
, that's why there is the ts error. this cannot be fixed in the type level alone, you need to check during runtime toonote here that you might want to check for the case of
{
itemsType: "video";
items: {
id: string;
url: string;
}[];
}
too, it satisfies
VideoType
but having the url
might not necessarily be what you want.Answer
Large oak-apple gallOP
I see, thanks