Skip to content

Error message improvements for unions with identical discriminants #42598

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

Closed

Conversation

DanielRosenwasser
Copy link
Member

@DanielRosenwasser DanielRosenwasser commented Feb 2, 2021

This PR would fix #40934, but we will be changing the core logic used in #42556.

However, I'm opening this because I wanted to point out the sorts of improvements changes we can see though if we're willing do a little extra work to track multiple object types with identical discriminants though. That logic can possibly be incorporated into #42556.

@DanielRosenwasser DanielRosenwasser added the Experiment A fork with an experimental idea which might not make it into master label Feb 2, 2021
Copy link
Member Author

@DanielRosenwasser DanielRosenwasser left a comment

Choose a reason for hiding this comment

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

Looking at this again, it's way more arguable. I think part of the approach that might be failing is that we're stopping at the first type, and not continuously refining the union of types given to us.

Comment on lines +44 to +54
foo2({
type2: 'y',
~~~~~~~~~~
!!! error TS2345: Argument of type '{ type2: "y"; value: "done"; method(): void; }' is not assignable to parameter of type 'X2 | Y2'.
!!! error TS2345: Object literal may only specify known properties, but 'type2' does not exist in type 'X2'. Did you mean to write 'type1'?
value: 'done',
method() {
this;
this.value;
}
});
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a new error - I'd argue this is actually a regression.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, isn’t this perfectly assignable to Y2?

Comment on lines +68 to +70
~~~~~~~~~~~
!!! error TS2322: Type '{ p1: "left"; p2: true; p3: number; p4: string; }' is not assignable to type 'DisjointDiscriminants'.
!!! error TS2322: Object literal may only specify known properties, and 'p4' does not exist in type '{ p1: "left"; p2: true; p3: number; }'.
Copy link
Member Author

Choose a reason for hiding this comment

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

This one is definitely an improvement.

Comment on lines 73 to +80
amb = { tag: "A", y: 12 }
~~~~~
!!! error TS2322: Type '{ tag: "A"; y: number; }' is not assignable to type 'Ambiguous'.
!!! error TS2322: Object literal may only specify known properties, and 'y' does not exist in type '{ tag: "A"; x: string; }'.
amb = { tag: "A", x: "hi", y: 12 }
~~~~~
!!! error TS2322: Type '{ tag: "A"; x: string; y: number; }' is not assignable to type 'Ambiguous'.
!!! error TS2322: Object literal may only specify known properties, and 'y' does not exist in type '{ tag: "A"; x: string; }'.
Copy link
Member Author

Choose a reason for hiding this comment

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

These are...ambiguous! Unclear if they should error.

Copy link
Member

@andrewbranch andrewbranch Feb 3, 2021

Choose a reason for hiding this comment

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

Wait, why should they be errors? Particularly the previous error on amb = { tag: "A", y: 12 } seems super wrong. But this one too seems like excess property checking is a little overzealous. For non-discriminated unions of objects, excess property checking only complains about properties non present in any constituent. Here, I would think the same rule would apply after we have filtered out the B and C constituents. So you should be allowed to supply x: string and y: number, but not z: boolean.

Comment on lines -82 to +88
~~~~~~~~~
~~~~~
Copy link
Member Author

Choose a reason for hiding this comment

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

Regression

Comment on lines 100 to +103
amb = { tag: "A", z: true }
~~~
~~~~~~~
!!! error TS2322: Type '{ tag: "A"; z: true; }' is not assignable to type 'Ambiguous'.
!!! error TS2322: Type '{ tag: "A"; z: true; }' is not assignable to type '{ tag: "B"; z: boolean; }'.
!!! error TS2322: Types of property 'tag' are incompatible.
!!! error TS2322: Type '"A"' is not assignable to type '"B"'.
!!! error TS2322: Object literal may only specify known properties, and 'z' does not exist in type '{ tag: "A"; x: string; }'.
Copy link
Member Author

Choose a reason for hiding this comment

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

This one is sort of an improvement - ideally, we'd be able to say that z was in another branch.

@andrewbranch
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 5, 2021

Heya @andrewbranch, I've started to run the tarball bundle task on this PR at a3b8ad2. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 5, 2021

Hey @andrewbranch, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/95115/artifacts?artifactName=tgz&fileId=C0B3D5B64589FB4C43656D06646358C3406739D7979063948B41AA3DA03B534302&fileName=/typescript-4.2.0-insiders.20210205.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/pr-build@4.2.0-pr-42598-2".;

@weswigham weswigham removed their request for review March 4, 2022 22:35
@sandersn
Copy link
Member

This experiment is pretty old, so I'm going to close it to reduce the number of open PRs.

@sandersn sandersn closed this May 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experiment A fork with an experimental idea which might not make it into master
Projects
None yet
4 participants