-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Improve logic that chooses co- vs. contra-variant return type inferences #59709
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
base: main
Are you sure you want to change the base?
Improve logic that chooses co- vs. contra-variant return type inferences #59709
Conversation
// and has inferences that would conflict. Otherwise, we prefer the contra-variant inference. | ||
// Similarly ignore co-variant `any` inference when both are available as almost everything is assignable to it | ||
// and it would spoil the overall inference. | ||
// ideally all inferences would be tried out in a ranked order but that's too costly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rewritten this comment based on the excellent comment by @weswigham here. I tried to be concise though as this is already pretty long and Wes' comment was even longer 😉 Feel free to suggest any improvement to this to make it better. I write better in TS than in English.
// however, for return types inferences subtyping is used. In those situations, the contravariant inference often comes from the argument of mapping function | ||
// and the outer covariant requirement can still be satisfied by the return position of the return type when it's a subtype of that required return type. | ||
// this helps to provide better contextual parameter types in scenarios like this: | ||
// | ||
// declare const obs: Observable<{ a?: string; b?: number }>; | ||
// const test = (): Observable<{ a?: string }> => obs.pipe(tap((arg) => {})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part of the comment tries to explain the idea behind the fix.
An alternative idea I had was to experiment with a new inference priority to differentiate between covariant inferences made from return positions. However, that's a bigger experiment and what I propose here is much safer at this stage. It's essentially reverting part of #57909 to 5.5 behavior. So it shouldn't behave worse in any case.
But also given that return positions could themselves be within nested functions, I don't have a good intuition on how it could play out. At the moment, there is no concept of "depth" in the inference and the core of this idea conceptually is that a return position might not be more important than a contravariant inference made from the (any?) containing function.
This would have some potential to solve Wes' concern raised here related to inferring from (x: number) => 0
to (x: T) => T
.
@typescript-bot test it |
Hey @jakebailey, the results of running the DT tests are ready. Everything looks the same! |
@jakebailey Here are the results of running the user tests with tsc comparing Everything looks good! |
@jakebailey Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
@jakebailey Here are the results of running the top 400 repos with tsc comparing Everything looks good! |
@typescript-bot pack this |
Hey @jakebailey, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running There is also a playground for this build and an npm module you can use via |
@typescript-bot test top999 |
@DanielRosenwasser Here are the results of running the top 999 repos with tsc comparing Everything looks good! |
fixes #59656
cc @weswigham as the reviewer of #57909 by which this got affected