Skip to content

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Andarist
Copy link
Contributor

fixes #59656
cc @weswigham as the reviewer of #57909 by which this got affected

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Aug 21, 2024
// 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
Copy link
Contributor Author

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.

Comment on lines +27004 to +27009
// 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) => {}));
Copy link
Contributor Author

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.

@jakebailey
Copy link
Member

@typescript-bot test it

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 21, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
test top400 ✅ Started ✅ Results
user test this ✅ Started ✅ Results
run dt ✅ Started ✅ Results
perf test this faster ✅ Started 👀 Results

@typescript-bot
Copy link
Collaborator

Hey @jakebailey, the results of running the DT tests are ready.

Everything looks the same!

You can check the log here.

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the user tests with tsc comparing main and refs/pull/59709/merge:

Everything looks good!

@typescript-bot
Copy link
Collaborator

@jakebailey
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - node (v18.15.0, x64)
Errors 30 30 ~ ~ ~ p=1.000 n=6
Symbols 62,153 62,153 ~ ~ ~ p=1.000 n=6
Types 50,242 50,242 ~ ~ ~ p=1.000 n=6
Memory used 193,608k (± 0.92%) 192,994k (± 0.77%) ~ 192,340k 196,046k p=0.936 n=6
Parse Time 1.30s (± 0.58%) 1.31s (± 0.39%) +0.01s (+ 0.90%) 1.31s 1.32s p=0.020 n=6
Bind Time 0.71s 0.71s ~ ~ ~ p=1.000 n=6
Check Time 9.60s (± 0.91%) 9.57s (± 0.41%) ~ 9.52s 9.61s p=0.467 n=6
Emit Time 2.72s (± 0.63%) 2.72s (± 1.03%) ~ 2.66s 2.74s p=0.560 n=6
Total Time 14.33s (± 0.62%) 14.31s (± 0.29%) ~ 14.26s 14.36s p=0.688 n=6
angular-1 - node (v18.15.0, x64)
Errors 7 7 ~ ~ ~ p=1.000 n=6
Symbols 945,753 945,753 ~ ~ ~ p=1.000 n=6
Types 410,067 410,067 ~ ~ ~ p=1.000 n=6
Memory used 1,222,694k (± 0.00%) 1,222,696k (± 0.00%) ~ 1,222,670k 1,222,728k p=0.936 n=6
Parse Time 6.66s (± 0.36%) 6.65s (± 0.44%) ~ 6.63s 6.71s p=0.684 n=6
Bind Time 1.86s (± 0.40%) 1.86s (± 0.53%) ~ 1.85s 1.88s p=0.858 n=6
Check Time 31.18s (± 0.44%) 31.14s (± 0.35%) ~ 30.99s 31.31s p=0.748 n=6
Emit Time 14.91s (± 0.56%) 14.98s (± 0.44%) ~ 14.89s 15.06s p=0.225 n=6
Total Time 54.60s (± 0.29%) 54.64s (± 0.26%) ~ 54.46s 54.79s p=1.000 n=6
mui-docs - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 2,517,779 2,517,779 ~ ~ ~ p=1.000 n=6
Types 994,242 994,242 ~ ~ ~ p=1.000 n=6
Memory used 2,442,563k (± 0.00%) 2,442,540k (± 0.00%) ~ 2,442,512k 2,442,577k p=0.230 n=6
Parse Time 9.30s (± 0.35%) 9.29s (± 0.38%) ~ 9.22s 9.32s p=0.366 n=6
Bind Time 2.20s (± 0.62%) 2.19s (± 0.45%) ~ 2.18s 2.20s p=0.673 n=6
Check Time 74.83s (± 0.29%) 74.77s (± 0.51%) ~ 74.16s 75.18s p=1.000 n=6
Emit Time 0.28s (± 3.19%) 0.28s (± 3.53%) ~ 0.27s 0.29s p=0.798 n=6
Total Time 86.60s (± 0.29%) 86.53s (± 0.44%) ~ 85.95s 86.95s p=0.936 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,231,998 1,231,999 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Types 264,593 264,593 ~ ~ ~ p=1.000 n=6
Memory used 2,472,512k (± 7.44%) 2,472,419k (± 7.44%) ~ 2,353,350k 2,710,065k p=0.810 n=6
Parse Time 6.04s (± 1.01%) 5.99s (± 0.62%) ~ 5.94s 6.04s p=0.128 n=6
Bind Time 2.26s (± 0.91%) 2.25s (± 1.20%) ~ 2.21s 2.29s p=0.418 n=6
Check Time 40.79s (± 0.79%) 40.76s (± 0.76%) ~ 40.23s 41.03s p=0.689 n=6
Emit Time 4.03s (± 0.87%) 4.01s (± 0.74%) ~ 3.96s 4.04s p=0.335 n=6
Total Time 53.14s (± 0.61%) 53.03s (± 0.56%) ~ 52.54s 53.37s p=0.575 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,231,998 1,231,999 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Types 264,593 264,593 ~ ~ ~ p=1.000 n=6
Memory used 2,428,294k (± 0.02%) 2,428,201k (± 0.02%) ~ 2,427,639k 2,428,911k p=0.689 n=6
Parse Time 6.24s (± 0.45%) 6.26s (± 0.95%) ~ 6.19s 6.34s p=0.689 n=6
Bind Time 2.04s (± 0.67%) 2.04s (± 1.41%) ~ 1.99s 2.07s p=0.808 n=6
Check Time 41.65s (± 0.63%) 41.85s (± 0.59%) ~ 41.46s 42.08s p=0.230 n=6
Emit Time 4.06s (± 0.63%) 4.06s (± 0.76%) ~ 4.03s 4.11s p=0.809 n=6
Total Time 53.99s (± 0.49%) 54.24s (± 0.54%) ~ 53.83s 54.55s p=0.173 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 256,992 256,993 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Types 105,667 105,667 ~ ~ ~ p=1.000 n=6
Memory used 429,722k (± 0.05%) 429,626k (± 0.03%) ~ 429,402k 429,751k p=0.810 n=6
Parse Time 2.79s (± 0.71%) 2.78s (± 0.60%) ~ 2.77s 2.81s p=0.222 n=6
Bind Time 1.08s (± 0.91%) 1.08s (± 1.12%) ~ 1.07s 1.10s p=0.388 n=6
Check Time 15.39s (± 0.35%) 15.36s (± 0.41%) ~ 15.28s 15.43s p=0.521 n=6
Emit Time 1.42s (± 1.07%) 1.40s (± 0.84%) ~ 1.38s 1.41s p=0.071 n=6
Total Time 20.68s (± 0.25%) 20.62s (± 0.39%) ~ 20.53s 20.74s p=0.172 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 68 68 ~ ~ ~ p=1.000 n=6
Symbols 225,018 225,018 ~ ~ ~ p=1.000 n=6
Types 94,249 94,249 ~ ~ ~ p=1.000 n=6
Memory used 370,188k (± 0.02%) 370,215k (± 0.02%) ~ 370,090k 370,318k p=0.689 n=6
Parse Time 2.77s (± 0.54%) 2.76s (± 1.16%) ~ 2.73s 2.81s p=0.625 n=6
Bind Time 1.58s (± 1.81%) 1.58s (± 0.74%) ~ 1.57s 1.60s p=0.560 n=6
Check Time 15.75s (± 0.24%) 15.78s (± 0.42%) ~ 15.68s 15.86s p=0.422 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 20.10s (± 0.24%) 20.12s (± 0.26%) ~ 20.04s 20.17s p=0.466 n=6
vscode - node (v18.15.0, x64)
Errors 66 66 ~ ~ ~ p=1.000 n=6
Symbols 3,020,870 3,020,870 ~ ~ ~ p=1.000 n=6
Types 1,039,240 1,039,240 ~ ~ ~ p=1.000 n=6
Memory used 3,140,085k (± 0.00%) 3,140,216k (± 0.00%) +131k (+ 0.00%) 3,140,127k 3,140,294k p=0.020 n=6
Parse Time 13.98s (± 0.46%) 14.02s (± 0.39%) ~ 13.93s 14.09s p=0.261 n=6
Bind Time 4.35s (± 2.05%) 4.30s (± 0.23%) ~ 4.29s 4.31s p=0.066 n=6
Check Time 80.07s (± 0.31%) 80.27s (± 0.62%) ~ 79.66s 80.86s p=0.378 n=6
Emit Time 20.50s (± 0.62%) 20.52s (± 0.80%) ~ 20.34s 20.70s p=0.936 n=6
Total Time 118.90s (± 0.23%) 119.11s (± 0.45%) ~ 118.43s 119.85s p=0.471 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 275,311 275,311 ~ ~ ~ p=1.000 n=6
Types 112,431 112,431 ~ ~ ~ p=1.000 n=6
Memory used 424,171k (± 0.02%) 424,189k (± 0.02%) ~ 424,072k 424,324k p=0.575 n=6
Parse Time 3.97s (± 0.47%) 3.98s (± 0.61%) ~ 3.94s 4.00s p=0.224 n=6
Bind Time 1.72s (± 0.68%) 1.72s (± 0.88%) ~ 1.70s 1.74s p=0.410 n=6
Check Time 17.51s (± 0.40%) 17.47s (± 0.73%) ~ 17.30s 17.59s p=0.810 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 23.19s (± 0.25%) 23.17s (± 0.62%) ~ 22.96s 23.32s p=1.000 n=6
xstate-main - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 534,554 534,554 ~ ~ ~ p=1.000 n=6
Types 176,379 176,379 ~ ~ ~ p=1.000 n=6
Memory used 479,444k (± 0.01%) 479,474k (± 0.01%) +30k (+ 0.01%) 479,408k 479,505k p=0.045 n=6
Parse Time 4.26s (± 1.04%) 4.28s (± 0.59%) ~ 4.25s 4.32s p=0.625 n=6
Bind Time 1.54s (± 0.95%) 1.54s (± 0.76%) ~ 1.53s 1.56s p=1.000 n=6
Check Time 22.48s (± 0.24%) 22.49s (± 0.37%) ~ 22.37s 22.60s p=0.810 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 28.28s (± 0.29%) 28.31s (± 0.33%) ~ 28.18s 28.46s p=0.521 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Compiler-Unions - node (v18.15.0, x64)
  • angular-1 - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-build-src-public-api - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • ts-pre-modules - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate-main - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the top 400 repos with tsc comparing main and refs/pull/59709/merge:

Everything looks good!

@jakebailey
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 22, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
pack this ✅ Started ✅ Results

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 22, 2024

Hey @jakebailey, 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/163412/artifacts?artifactName=tgz&fileId=FC442BACFFC913E8502821A0DD902D0764AF8ADC5017DFEDA553B3332B29087102&fileName=/typescript-5.7.0-insiders.20240822.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/[email protected]".;

@DanielRosenwasser
Copy link
Member

@typescript-bot test top999

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 22, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
test top999 ✅ Started ✅ Results

@typescript-bot
Copy link
Collaborator

@DanielRosenwasser Here are the results of running the top 999 repos with tsc comparing main and refs/pull/59709/merge:

Everything looks good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Status: Not started
Development

Successfully merging this pull request may close these issues.

5.6 regression: Incorrect param type inference for type with all optional props
4 participants