-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Use assignability relation in Best Common Type when checking contextual type against candidates #644
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
Comments
Running through all the places we use BCT:
var z: { [s: string]: Animal };
z = { // Desired: No error
'a': new Animal(),
'd': new Dog()
};
var a: Animal;
a = a || (new Dog()); // Desired: no error
var a: Animal;
a = true ? a : (new Dog()); // Desired: no error
|
I think this is a very good idea. Simple, and very unlikely to break anything. One thing: "Important to note that we need to use a subtype relationship check here instead of assignability so that null/undefined/any types don't 'poison' arrays" - null and undefined are actually not concerning here because they do not get widened until after best common type (and if there is a contextual type they never get widened at all). |
Here's an interesting thought. Once we change this to assignability, why even have the quadratic subtype pass afterward? Why not just fall to
This seems equivalent to the old algorithm because in the old one, one of two things would happen after the assignability pass fails
There are two potential differences between the 2 algorithms:
With union types (#805), the old BCT algorithm (with a contextual type) becomes weird. It essentially would go like this:
A lot of this is repetitive and redundant. At the end of the day, we just want to check that all candidates are assignable to the contextual type. |
This is resolved by union types |
Code examples:
Our current error is:
This is because the contextual type is not a supertype of all the candidate types, nor is any candidate type a supertype of the rest. We do need to use a subtype relationship check here instead of assignability (when checking among candidates) so that
any
values properly cause arrays to be of typeany[]
(e.g.[number, string, any]
should beany[]
, not{}[]
).The current spec for Best Common Type (3.10) says:
In the second bullet, we use the subtype/supertype relation. However, when a contextual type is present, we know the next thing we're going to do after computing the BCT is to check that BCT for assignability against the contextual type. Even though we can't use the assignability relation when finding a 'best' type among the candidates, it still makes sense to use the assignability relation when attempting to use the contextual type because this is the relation we're going to try to satisfy anyway.
Instead, this should be:
This fixes all of the examples above and below.
The text was updated successfully, but these errors were encountered: