-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Description
Bug Report
Please feel free to change the title to make it more accurate. I wasn't sure what to call this
π Search Terms
union narrow
π Version & Regression Information
5.1.6
β― Playground Link
Playground link with relevant code
π» Code
export type DomNodeStyle = ElementStyle | ImageStyle;
export type ElementStyle = {
tagName: string;
style: { key: string; value: string }[];
children: (ElementStyle | ContentStyle)[];
};
export type ContentStyle = { content: string };
export type ImageStyle = {
tagName: 'img';
imageSource: string | null;
style: { key: string; value: string }[];
children: (ElementStyle | ContentStyle)[];
};
const image = {
tagName: 'img',
imageSource: 'https://example.com/image.jpg', // This is correct. Compiler requires `imageSource` because tagName is `img`.
style: [],
children: []
};
function doSomeWork(node: DomNodeStyle) {
if (image.tagName === "img") { // Narrowing is not occurring correctly
console.log(image.imageSource) // Error message: Property 'imageSource' does not exist on type 'ElementStyle'
}
}π Actual behavior
For a partially discriminated union, when trying to access a narrowed field value, the compiler does not properly narrow the type. This forces the user to use the in operator to determine if the field exists. When instantiating the object though, the compiler does correctly infer that the field from the narrowed type needs to exist.
π Expected behavior
I would expect the compiler to properly narrow the type if the explicitly defined union is set. In this case, if tagName is img, the compiler should infer that imageSource is required and available. If tagName is any other string value, the compiler should fall back to ElementStyle for the type.