Skip to content

Do not consider binding patterns in contextual types for return type … #39081

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged

Conversation

weswigham
Copy link
Member

@weswigham weswigham commented Jun 15, 2020

…inference where all the signature type parameters have defaults

Fixes #38969

So, when I was looking into #38969 I was tempted to call it working as intended, as it's a logical fallout of current rules for inference and contextual typing; but that felt really unsatisfying, as we know that binding pattern shapes are rather poor inference targets. I went through a few iterations, but here have settled on the simple addition of a new heuristic for inference: If all type parameters the signature we're inferring to have defaults, then we disable the usage of binding patterns in contextual type lookup, which, in turn, allows us to fallback to using those defaults, over those binding pattern types.

…inference where all the signature type parameters have defaults
@weswigham
Copy link
Member Author

@typescript-bot user test this
@typescript-bot test this
@typescript-bot run dt
@typescript-bot perf test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 15, 2020

Heya @weswigham, I've started to run the parallelized Definitely Typed test suite on this PR at a42e1ae. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 15, 2020

Heya @weswigham, I've started to run the perf test suite on this PR at a42e1ae. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 15, 2020

Heya @weswigham, I've started to run the parallelized community code test suite on this PR at a42e1ae. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 15, 2020

Heya @weswigham, I've started to run the extended test suite on this PR at a42e1ae. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master.

@weswigham
Copy link
Member Author

User baselines are fine, as are rwc baselines. DT has one new failure, in react-router, which has a single test doing

const { id } = useParams();

useParams has a default on it's return type type parameter of {} (yes, we have a lint rule forbidding this, yes, they suppress that rule), so this new error seems reasonable to me (it's the expected fallout, at least). Simply removing the default can restore the old behavior, if it's desirable (which, to me, seems questionable, as it leaks anys into the program and the intent of the type would seem to be only allowing indexes to strings, but what do I know). You can actually get a type for the signature which works better (ie, doesn't produce anys), and is forward compatible with this change (albeit in a more complex way) using

export function useParams<Params extends { [K in keyof Params]?: string }>(): {[K in keyof Params]: Params[K] extends never ? string : Params[K]};

@typescript-bot
Copy link
Collaborator

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

Here they are:

Comparison Report - master..39081

Metric master 39081 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 328,370k (± 0.02%) 328,057k (± 0.01%) -313k (- 0.10%) 327,945k 328,161k
Parse Time 1.65s (± 0.45%) 1.65s (± 0.71%) -0.00s (- 0.12%) 1.62s 1.67s
Bind Time 0.92s (± 1.10%) 0.91s (± 0.66%) -0.01s (- 0.98%) 0.89s 0.92s
Check Time 4.87s (± 0.50%) 4.87s (± 0.48%) +0.00s (+ 0.06%) 4.83s 4.93s
Emit Time 5.42s (± 0.31%) 5.42s (± 0.82%) -0.00s (- 0.02%) 5.34s 5.53s
Total Time 12.85s (± 0.28%) 12.84s (± 0.40%) -0.01s (- 0.08%) 12.75s 12.97s
Monaco - node (v10.16.3, x64)
Memory used 327,439k (± 0.02%) 327,431k (± 0.02%) -9k (- 0.00%) 327,356k 327,560k
Parse Time 1.27s (± 0.91%) 1.27s (± 1.03%) +0.00s (+ 0.08%) 1.25s 1.31s
Bind Time 0.80s (± 0.86%) 0.79s (± 0.60%) -0.00s (- 0.38%) 0.78s 0.80s
Check Time 4.90s (± 0.61%) 4.91s (± 0.40%) +0.01s (+ 0.29%) 4.86s 4.95s
Emit Time 2.96s (± 0.68%) 2.95s (± 0.81%) -0.01s (- 0.20%) 2.91s 3.01s
Total Time 9.92s (± 0.52%) 9.93s (± 0.46%) +0.01s (+ 0.09%) 9.84s 10.05s
TFS - node (v10.16.3, x64)
Memory used 292,600k (± 0.02%) 292,569k (± 0.02%) -31k (- 0.01%) 292,408k 292,737k
Parse Time 0.96s (± 0.73%) 0.95s (± 0.38%) -0.01s (- 0.52%) 0.95s 0.96s
Bind Time 0.77s (± 0.68%) 0.76s (± 0.48%) -0.00s (- 0.65%) 0.76s 0.77s
Check Time 4.40s (± 0.28%) 4.40s (± 0.36%) -0.00s (- 0.11%) 4.36s 4.44s
Emit Time 3.08s (± 0.78%) 3.09s (± 0.51%) +0.01s (+ 0.16%) 3.06s 3.13s
Total Time 9.21s (± 0.36%) 9.20s (± 0.31%) -0.01s (- 0.10%) 9.14s 9.27s
material-ui - node (v10.16.3, x64)
Memory used 450,097k (± 0.02%) 449,429k (± 0.01%) -668k (- 0.15%) 449,370k 449,511k
Parse Time 1.79s (± 0.41%) 1.79s (± 0.46%) -0.00s (- 0.22%) 1.77s 1.81s
Bind Time 0.71s (± 1.07%) 0.70s (± 0.47%) -0.01s (- 0.85%) 0.69s 0.71s
Check Time 12.82s (± 0.77%) 12.86s (± 0.83%) +0.04s (+ 0.30%) 12.69s 13.20s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.32s (± 0.65%) 15.35s (± 0.69%) +0.03s (+ 0.18%) 15.17s 15.68s
Angular - node (v12.1.0, x64)
Memory used 303,940k (± 0.04%) 303,658k (± 0.03%) -282k (- 0.09%) 303,424k 303,914k
Parse Time 1.61s (± 0.92%) 1.60s (± 0.50%) -0.01s (- 0.62%) 1.58s 1.62s
Bind Time 0.89s (± 0.75%) 0.89s (± 0.69%) -0.00s (- 0.11%) 0.88s 0.90s
Check Time 4.74s (± 0.44%) 4.74s (± 0.45%) -0.00s (- 0.04%) 4.67s 4.78s
Emit Time 5.59s (± 1.26%) 5.57s (± 0.75%) -0.02s (- 0.27%) 5.49s 5.67s
Total Time 12.83s (± 0.64%) 12.79s (± 0.39%) -0.03s (- 0.27%) 12.70s 12.91s
Monaco - node (v12.1.0, x64)
Memory used 307,358k (± 0.02%) 307,352k (± 0.01%) -6k (- 0.00%) 307,261k 307,430k
Parse Time 1.23s (± 0.49%) 1.22s (± 0.51%) -0.01s (- 0.49%) 1.20s 1.23s
Bind Time 0.77s (± 0.61%) 0.77s (± 0.90%) -0.00s (- 0.65%) 0.75s 0.78s
Check Time 4.70s (± 0.53%) 4.70s (± 0.53%) -0.00s (- 0.02%) 4.65s 4.77s
Emit Time 2.99s (± 0.74%) 3.00s (± 0.84%) +0.01s (+ 0.37%) 2.94s 3.05s
Total Time 9.68s (± 0.34%) 9.69s (± 0.49%) +0.01s (+ 0.06%) 9.59s 9.83s
TFS - node (v12.1.0, x64)
Memory used 274,825k (± 0.02%) 274,895k (± 0.02%) +70k (+ 0.03%) 274,819k 275,042k
Parse Time 0.93s (± 0.53%) 0.93s (± 0.39%) -0.01s (- 0.86%) 0.92s 0.93s
Bind Time 0.75s (± 1.27%) 0.74s (± 1.00%) -0.00s (- 0.40%) 0.73s 0.76s
Check Time 4.31s (± 0.33%) 4.30s (± 0.28%) -0.01s (- 0.21%) 4.26s 4.32s
Emit Time 3.11s (± 0.58%) 3.13s (± 0.64%) +0.01s (+ 0.42%) 3.10s 3.19s
Total Time 9.10s (± 0.22%) 9.10s (± 0.28%) -0.01s (- 0.07%) 9.05s 9.16s
material-ui - node (v12.1.0, x64)
Memory used 427,408k (± 0.05%) 426,730k (± 0.05%) -678k (- 0.16%) 425,822k 426,927k
Parse Time 1.77s (± 0.53%) 1.76s (± 0.42%) -0.01s (- 0.56%) 1.75s 1.79s
Bind Time 0.65s (± 1.26%) 0.65s (± 0.51%) +0.00s (+ 0.46%) 0.64s 0.66s
Check Time 11.48s (± 0.77%) 11.46s (± 0.66%) -0.02s (- 0.21%) 11.36s 11.68s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 13.90s (± 0.68%) 13.87s (± 0.55%) -0.03s (- 0.23%) 13.75s 14.10s
Angular - node (v8.9.0, x64)
Memory used 323,361k (± 0.02%) 323,016k (± 0.02%) -346k (- 0.11%) 322,869k 323,205k
Parse Time 2.12s (± 0.29%) 2.12s (± 0.52%) +0.00s (+ 0.14%) 2.10s 2.15s
Bind Time 0.94s (± 0.88%) 0.94s (± 0.90%) -0.00s (- 0.42%) 0.93s 0.97s
Check Time 5.53s (± 1.78%) 5.55s (± 1.12%) +0.03s (+ 0.52%) 5.31s 5.61s
Emit Time 6.37s (± 2.48%) 6.31s (± 0.88%) -0.06s (- 0.88%) 6.16s 6.43s
Total Time 14.96s (± 0.59%) 14.93s (± 0.43%) -0.03s (- 0.20%) 14.78s 15.09s
Monaco - node (v8.9.0, x64)
Memory used 326,072k (± 0.01%) 326,091k (± 0.02%) +19k (+ 0.01%) 325,973k 326,167k
Parse Time 1.55s (± 0.30%) 1.54s (± 0.32%) -0.01s (- 0.32%) 1.54s 1.56s
Bind Time 0.92s (± 1.11%) 0.92s (± 1.27%) 0.00s ( 0.00%) 0.91s 0.96s
Check Time 5.47s (± 0.52%) 5.48s (± 0.59%) +0.01s (+ 0.18%) 5.41s 5.56s
Emit Time 3.48s (± 0.80%) 3.50s (± 0.74%) +0.01s (+ 0.43%) 3.45s 3.55s
Total Time 11.42s (± 0.34%) 11.44s (± 0.44%) +0.02s (+ 0.18%) 11.34s 11.55s
TFS - node (v8.9.0, x64)
Memory used 292,236k (± 0.01%) 292,214k (± 0.02%) -22k (- 0.01%) 292,099k 292,390k
Parse Time 1.26s (± 0.47%) 1.25s (± 0.39%) -0.00s (- 0.16%) 1.25s 1.27s
Bind Time 0.76s (± 0.99%) 0.76s (± 0.96%) -0.01s (- 0.79%) 0.74s 0.77s
Check Time 5.03s (± 2.18%) 5.04s (± 1.75%) +0.01s (+ 0.22%) 4.89s 5.21s
Emit Time 3.26s (± 2.69%) 3.28s (± 3.14%) +0.02s (+ 0.71%) 3.10s 3.49s
Total Time 10.31s (± 0.42%) 10.34s (± 0.38%) +0.02s (+ 0.24%) 10.29s 10.46s
material-ui - node (v8.9.0, x64)
Memory used 453,098k (± 0.01%) 452,492k (± 0.01%) -606k (- 0.13%) 452,350k 452,587k
Parse Time 2.13s (± 0.58%) 2.12s (± 0.47%) -0.01s (- 0.42%) 2.10s 2.15s
Bind Time 0.82s (± 0.85%) 0.82s (± 1.15%) +0.00s (+ 0.24%) 0.81s 0.85s
Check Time 16.89s (± 0.68%) 16.87s (± 0.57%) -0.01s (- 0.09%) 16.64s 17.03s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 19.84s (± 0.62%) 19.82s (± 0.52%) -0.02s (- 0.13%) 19.58s 20.03s
Angular - node (v8.9.0, x86)
Memory used 186,352k (± 0.03%) 186,186k (± 0.03%) -166k (- 0.09%) 186,055k 186,289k
Parse Time 2.07s (± 0.76%) 2.05s (± 0.70%) -0.02s (- 0.92%) 2.03s 2.10s
Bind Time 1.09s (± 0.62%) 1.08s (± 0.45%) -0.01s (- 0.91%) 1.07s 1.09s
Check Time 5.11s (± 0.54%) 5.09s (± 0.48%) -0.02s (- 0.45%) 5.03s 5.14s
Emit Time 6.15s (± 0.84%) 6.13s (± 0.86%) -0.01s (- 0.23%) 6.04s 6.26s
Total Time 14.42s (± 0.45%) 14.36s (± 0.44%) -0.06s (- 0.43%) 14.17s 14.45s
Monaco - node (v8.9.0, x86)
Memory used 185,907k (± 0.02%) 185,884k (± 0.02%) -24k (- 0.01%) 185,823k 185,954k
Parse Time 1.61s (± 0.85%) 1.60s (± 0.58%) -0.01s (- 0.50%) 1.59s 1.63s
Bind Time 0.78s (± 0.87%) 0.78s (± 0.93%) -0.00s (- 0.26%) 0.77s 0.80s
Check Time 5.53s (± 0.47%) 5.50s (± 0.46%) -0.03s (- 0.51%) 5.45s 5.57s
Emit Time 2.90s (± 0.73%) 2.88s (± 0.55%) -0.02s (- 0.69%) 2.84s 2.91s
Total Time 10.82s (± 0.44%) 10.76s (± 0.28%) -0.06s (- 0.51%) 10.70s 10.84s
TFS - node (v8.9.0, x86)
Memory used 167,519k (± 0.03%) 167,551k (± 0.02%) +32k (+ 0.02%) 167,487k 167,630k
Parse Time 1.30s (± 0.54%) 1.30s (± 0.57%) +0.00s (+ 0.08%) 1.29s 1.32s
Bind Time 0.73s (± 0.82%) 0.73s (± 1.21%) +0.00s (+ 0.14%) 0.71s 0.75s
Check Time 4.72s (± 0.64%) 4.70s (± 0.72%) -0.02s (- 0.42%) 4.64s 4.78s
Emit Time 2.98s (± 0.89%) 3.03s (± 2.23%) +0.05s (+ 1.68%) 2.96s 3.25s
Total Time 9.73s (± 0.41%) 9.76s (± 0.82%) +0.03s (+ 0.32%) 9.64s 9.97s
material-ui - node (v8.9.0, x86)
Memory used 256,773k (± 0.01%) 256,437k (± 0.01%) -336k (- 0.13%) 256,372k 256,500k
Parse Time 2.19s (± 0.43%) 2.19s (± 0.51%) +0.00s (+ 0.05%) 2.17s 2.22s
Bind Time 0.70s (± 1.00%) 0.70s (± 1.32%) +0.00s (+ 0.43%) 0.68s 0.73s
Check Time 15.56s (± 0.88%) 15.57s (± 0.61%) +0.01s (+ 0.04%) 15.37s 15.90s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 18.45s (± 0.74%) 18.46s (± 0.55%) +0.01s (+ 0.05%) 18.22s 18.79s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-166-generic
Architecturex64
Available Memory16 GB
Available Memory1 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v8.9.0, x64)
  • node (v8.9.0, x86)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v8.9.0, x64)
  • Angular - node (v8.9.0, x86)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v8.9.0, x64)
  • Monaco - node (v8.9.0, x86)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v8.9.0, x64)
  • TFS - node (v8.9.0, x86)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v8.9.0, x64)
  • material-ui - node (v8.9.0, x86)
Benchmark Name Iterations
Current 39081 10
Baseline master 10

@weswigham
Copy link
Member Author

And perf is fine, not that I expected a diff.

Copy link
Member

@andrewbranch andrewbranch left a comment

Choose a reason for hiding this comment

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

This seems totally reasonable to me. I’m a bit surprised we ever inferred from binding patterns in the first place.

@weswigham
Copy link
Member Author

@ahejlsberg wanna take a look at this? I know we've discussed how we handle binding pattern contextual types (and how odd they are) before.

@weswigham weswigham merged commit d1ebf12 into microsoft:master Jun 24, 2020
@weswigham weswigham deleted the destruct-type-same-as-shorthand branch June 24, 2020 20:45
@ahejlsberg
Copy link
Member

BTW, looks like this would fix #32003, yes?

@weswigham
Copy link
Member Author

easy way to find out: @typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 24, 2020

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

@weswigham
Copy link
Member Author

sigh man that merge commit got deleted the moment I deleted the branch. Anyways, from local testing: Yep, this fixes #32003. So long as the type parameter has a default, we'll prefer it in return type inference over a binding pattern.

cangSDARM added a commit to cangSDARM/TypeScript that referenced this pull request Jun 28, 2020
* upstream/master:
  LEGO: check in for master to temporary branch.
  Preserve newlines between try/catch/finally, if/else, do/while (microsoft#39280)
  not narrow static property without type annotation in constructor. (microsoft#39252)
  Switch to ES Map/Set internally (microsoft#33771)
  fix(38840): omit completions for a spread like argument in a function definition (microsoft#38897)
  fix(38785): include in NavigationBar child items from default exported functions (microsoft#38915)
  LEGO: check in for master to temporary branch.
  LEGO: check in for master to temporary branch.
  Avoid effect of element access expression (microsoft#39174)
  Update typescript-eslint to 3.4.1-alpha.1 (microsoft#39260)
  Handle 'keyof' for generic tuple types (microsoft#39218)
  Disable unsound T[K] rule in subtype relations (microsoft#39249)
  LEGO: check in for master to temporary branch.
  Upgrade typescript-eslint version (microsoft#39242)
  Handle recursive type references up to a certain level of expansion in inference (microsoft#38011)
  Do not consider binding patterns in contextual types for return type inference where all the signature type parameters have defaults (microsoft#39081)
  LEGO: check in for master to temporary branch.

# Conflicts:
#	src/compiler/program.ts
#	src/compiler/types.ts
sandersn added a commit to DefinitelyTyped/DefinitelyTyped that referenced this pull request Jun 29, 2020
microsoft/TypeScript#39081, which ships in Typescript 4.0, stops using
binding patterns as contextual types for return type inference.
react-router's `useParams` relied on this to fill in an object with
`any`s in case a binding pattern was used but no type argument was
provided. This no longer works.

This fix just adds a type argument to the tests.

For two other, more complete fixes, see

microsoft/TypeScript#39081 (comment)

Briefly, the options are (1) go back to returning `any`-filled object
types or (2) tries to default to `string`.

The second fix is probably the right one, but it may hurt
compilation/IDE performance, so I'll leave it to the package owners to
decide whether to make that change.
typescript-bot pushed a commit to DefinitelyTyped/DefinitelyTyped that referenced this pull request Jun 29, 2020
microsoft/TypeScript#39081, which ships in Typescript 4.0, stops using
binding patterns as contextual types for return type inference.
react-router's `useParams` relied on this to fill in an object with
`any`s in case a binding pattern was used but no type argument was
provided. This no longer works.

This fix just adds a type argument to the tests.

For two other, more complete fixes, see

microsoft/TypeScript#39081 (comment)

Briefly, the options are (1) go back to returning `any`-filled object
types or (2) tries to default to `string`.

The second fix is probably the right one, but it may hurt
compilation/IDE performance, so I'll leave it to the package owners to
decide whether to make that change.
ngbrown pushed a commit to ngbrown-forks/DefinitelyTyped that referenced this pull request Jul 11, 2020
…ersn

microsoft/TypeScript#39081, which ships in Typescript 4.0, stops using
binding patterns as contextual types for return type inference.
react-router's `useParams` relied on this to fill in an object with
`any`s in case a binding pattern was used but no type argument was
provided. This no longer works.

This fix just adds a type argument to the tests.

For two other, more complete fixes, see

microsoft/TypeScript#39081 (comment)

Briefly, the options are (1) go back to returning `any`-filled object
types or (2) tries to default to `string`.

The second fix is probably the right one, but it may hurt
compilation/IDE performance, so I'll leave it to the package owners to
decide whether to make that change.
danielrearden pushed a commit to danielrearden/DefinitelyTyped that referenced this pull request Sep 22, 2020
…ersn

microsoft/TypeScript#39081, which ships in Typescript 4.0, stops using
binding patterns as contextual types for return type inference.
react-router's `useParams` relied on this to fill in an object with
`any`s in case a binding pattern was used but no type argument was
provided. This no longer works.

This fix just adds a type argument to the tests.

For two other, more complete fixes, see

microsoft/TypeScript#39081 (comment)

Briefly, the options are (1) go back to returning `any`-filled object
types or (2) tries to default to `string`.

The second fix is probably the right one, but it may hurt
compilation/IDE performance, so I'll leave it to the package owners to
decide whether to make that change.
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Destructuring with rename incorrectly inferred as any
4 participants