Skip to content

Improved errors using type reference targets#25115

Merged
DanielRosenwasser merged 6 commits intomasterfrom
matchingTypeRefs
Jun 21, 2018
Merged

Improved errors using type reference targets#25115
DanielRosenwasser merged 6 commits intomasterfrom
matchingTypeRefs

Conversation

@DanielRosenwasser
Copy link
Copy Markdown
Member

@DanielRosenwasser DanielRosenwasser commented Jun 21, 2018

Fixes #24776

This pull request should improve error messages when assigning type references to union types when a target type contains a type reference whose target type matches the source's.

As an example,

interface A<T> {
    aProp: T;
}

interface B<T> {
    bProp: T;
}

interface C<T> {
    cProp: T;
}

declare const a: A<Foo>;
declare let thing: A<Bar> | B<Baz> | C<Kwah>;

thing = a;

Previously we would report

Type 'A<Foo>' is not assignable to type 'A<Bar> | B<Baz>'.
  Type 'A<Foo>' is not assignable to type 'B<Baz>'.
    Property 'bProp' is missing in type 'A<Foo>'.

Notice that we try to use B<Baz> to explain the incompatibility. Intuitively, we'd assume that A<Bar> is probably what the user wanted to assign to.

With this change, we report a more relevant error:

Type 'A<Foo>' is not assignable to type 'A<Bar> | B<Baz>'.
  Type 'A<Foo>' is not assignable to type 'A<Bar>'.
    Property 'bar' is missing in type 'Foo'.

Currently I'm trying to get this to also work for anonymous types which have a well-associated alias type, however, I might need help there (@weswigham @sandersn).

As future work, we can

  • use inheritance chains of each type's target, since there may be cases when users relate a Derived to a Base<Foo>
  • make this work when the source is an intersection types as well
  • make this work on other type operators

@DanielRosenwasser DanielRosenwasser changed the title [WIP] Improved errors using type reference targets Improved errors using type reference targets Jun 21, 2018
Copy link
Copy Markdown
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

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

Good improvement, and we can keep iterating on it. We may want to unify the two loops over the union members we do here so we avoid iterating the list twice, but that can be done in the future if its needed.

Comment thread src/compiler/checker.ts
if ((source as ObjectType).objectFlags & (target as ObjectType).objectFlags & ObjectFlags.Reference) {
return (source as TypeReference).target === (target as TypeReference).target;
}
if ((source as ObjectType).objectFlags & (target as ObjectType).objectFlags & ObjectFlags.Anonymous) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use getObjectFlags instead of (source as ObjectType).objectFlags

@sandersn
Copy link
Copy Markdown
Member

It's odd that only one baseline changed besides the new test, and the change is not an improvement (although not much of a regression since it was quite confusing already). Does this change the user test or RWC test baselines? If so, do those error message look better?

@weswigham
Copy link
Copy Markdown
Member

It's odd that only one baseline changed besides the new test, and the change is not an improvement (although not much of a regression since it was quite confusing already).

It's just selecting the first type instead of the last, since both are references to the tuple type.

@sandersn
Copy link
Copy Markdown
Member

Oops, what I really meant to say was that it's odd that only one baseline changed. And also the one change isn't an improvement, which isn't odd because it's hard to change things without breaking something. Together, the two things make me wonder whether any more changes exist so that we can know whether they are improvements or not.

@DanielRosenwasser
Copy link
Copy Markdown
Member Author

I agree; I was pretty disappointed to see the lack of improvement in the existing test suite. Maybe we'll see improvements in the RWC errors though.

@DanielRosenwasser DanielRosenwasser merged commit 72068e2 into master Jun 21, 2018
@DanielRosenwasser DanielRosenwasser deleted the matchingTypeRefs branch June 21, 2018 20:46
@microsoft microsoft locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants