Skip to content

Disallow partial matches for discriminant properties when generating error messages #37589

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

weswigham
Copy link
Member

Fixes #37506

In the example given, data is marked as a discriminable property, because for the members it exists on, it can discriminate between them; so, taken with another (potentially partial) discriminant, it may discriminate the whole union (we have tests to that effect). Unfortunately, allowing such partial discriminants when choosing error targets makes us pick some suboptimal error messages; so in this PR, we disallow "partial" union properties from being enumerated as possible discriminant properties when fetching a discriminated union member for error elaboration purposes.

@@ -37852,13 +37856,13 @@ namespace ts {
}

// Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly
function findMatchingDiscriminantType(source: Type, target: Type, isRelatedTo: (source: Type, target: Type) => Ternary) {
function findMatchingDiscriminantType(source: Type, target: Type, isRelatedTo: (source: Type, target: Type) => Ternary, skipPartial?: boolean) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When do you not want to skipPartial discriminants?

Copy link
Member Author

@weswigham weswigham Mar 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we report excess property errors on something like

type Group = {a: 1, b: 1, field: string, data: string}; | {a: 2, field: string} | {b: 2, data: string};
const x: Group = {a: 1, b: 1, field: "ok", data: "ok", excess: "not ok"};

a and b are both partial discriminants, but taken together, can discriminate to the first member. We have a test expecting this.

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am convinced it will work, but we should keep an eye on RWC and user tests after this for unintended consequences.

@weswigham weswigham merged commit 326e1c9 into microsoft:master Apr 1, 2020
@weswigham weswigham deleted the sometimes-disable-partial-discriminants branch April 1, 2020 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error message indicates incorrect union discriminant
4 participants