Skip to content
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

Add infer T constraint inference rule matching up mapped type templates across check/extends types #43649

Merged
merged 1 commit into from
Apr 21, 2021

Conversation

weswigham
Copy link
Member

Fixes #43357

The example in the issue used to work, I assume, due to some flawed conditional type assignability (or instantiation/constraint) rules we used to have. Inherently, there's no reason it should have worked, since U is unconstrained. By adding a constraint inference site for this example, we can get it to succeed now that we have proper rules for relating conditionals in place. More generally, if we wanted to move from syntactic matching for this case (and broaden how applicable this fix is), we could do inference between the source and target sides of the containing uninstantiated conditional, and rely on inference to match the infer X location up to an appropriate constraint location instead; but doing so in general could be breaky in the community, since using infer constraints to break constraint relationships in our calculations is relatively common.

@typescript-bot typescript-bot added Author: Team For Milestone Bug PRs that fix a bug with a specific milestone labels Apr 12, 2021
@weswigham
Copy link
Member Author

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 12, 2021

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 12, 2021

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 12, 2021

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 12, 2021

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

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 12, 2021

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 12, 2021

Hey @weswigham, 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/100767/artifacts?artifactName=tgz&fileId=10EFFEEFCD96558560CB3141E0874D7808B4D1F05B756E75FB3129D074F721A602&fileName=/typescript-4.3.0-insiders.20210412.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/pr-build@4.3.0-pr-43649-6".;

@typescript-bot
Copy link
Collaborator

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

Here they are:

Comparison Report - master..43649

Metric master 43649 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 345,025k (± 0.01%) 345,115k (± 0.03%) +90k (+ 0.03%) 344,916k 345,352k
Parse Time 1.94s (± 0.55%) 1.94s (± 0.82%) +0.00s (+ 0.21%) 1.92s 1.98s
Bind Time 0.83s (± 0.82%) 0.83s (± 0.44%) 0.00s ( 0.00%) 0.83s 0.84s
Check Time 5.19s (± 0.35%) 5.19s (± 0.42%) +0.01s (+ 0.12%) 5.13s 5.23s
Emit Time 5.93s (± 0.48%) 5.95s (± 0.46%) +0.02s (+ 0.29%) 5.91s 6.04s
Total Time 13.88s (± 0.35%) 13.92s (± 0.38%) +0.03s (+ 0.24%) 13.81s 14.09s
Compiler-Unions - node (v10.16.3, x64)
Memory used 203,356k (± 0.12%) 203,414k (± 0.03%) +58k (+ 0.03%) 203,322k 203,509k
Parse Time 0.78s (± 0.67%) 0.79s (± 0.71%) +0.01s (+ 0.90%) 0.78s 0.80s
Bind Time 0.52s (± 1.11%) 0.52s (± 0.86%) -0.01s (- 0.96%) 0.51s 0.53s
Check Time 7.46s (± 0.53%) 7.49s (± 0.61%) +0.03s (+ 0.40%) 7.41s 7.62s
Emit Time 2.58s (± 0.36%) 2.57s (± 0.68%) -0.02s (- 0.62%) 2.54s 2.60s
Total Time 11.35s (± 0.39%) 11.36s (± 0.51%) +0.02s (+ 0.14%) 11.25s 11.53s
Monaco - node (v10.16.3, x64)
Memory used 342,709k (± 0.02%) 342,815k (± 0.03%) +106k (+ 0.03%) 342,660k 343,176k
Parse Time 1.56s (± 0.33%) 1.55s (± 0.52%) -0.01s (- 0.58%) 1.54s 1.58s
Bind Time 0.75s (± 1.20%) 0.74s (± 0.98%) -0.00s (- 0.40%) 0.73s 0.76s
Check Time 5.33s (± 0.35%) 5.32s (± 0.44%) -0.01s (- 0.21%) 5.25s 5.37s
Emit Time 3.13s (± 1.01%) 3.11s (± 0.55%) -0.02s (- 0.61%) 3.08s 3.16s
Total Time 10.76s (± 0.41%) 10.71s (± 0.36%) -0.04s (- 0.41%) 10.61s 10.80s
TFS - node (v10.16.3, x64)
Memory used 304,376k (± 0.01%) 304,355k (± 0.02%) -20k (- 0.01%) 304,247k 304,501k
Parse Time 1.22s (± 0.83%) 1.21s (± 0.63%) -0.01s (- 0.90%) 1.19s 1.22s
Bind Time 0.70s (± 0.97%) 0.70s (± 0.48%) -0.00s (- 0.14%) 0.70s 0.71s
Check Time 4.78s (± 0.64%) 4.78s (± 0.60%) -0.00s (- 0.08%) 4.72s 4.85s
Emit Time 3.26s (± 1.22%) 3.25s (± 1.01%) -0.01s (- 0.43%) 3.13s 3.29s
Total Time 9.97s (± 0.47%) 9.93s (± 0.46%) -0.03s (- 0.34%) 9.79s 9.99s
material-ui - node (v10.16.3, x64)
Memory used 466,095k (± 0.01%) 466,049k (± 0.01%) -46k (- 0.01%) 465,903k 466,205k
Parse Time 2.01s (± 0.38%) 2.01s (± 0.62%) +0.00s (+ 0.00%) 1.98s 2.03s
Bind Time 0.66s (± 1.05%) 0.66s (± 1.52%) +0.00s (+ 0.31%) 0.64s 0.68s
Check Time 14.31s (± 0.42%) 14.28s (± 0.39%) -0.03s (- 0.22%) 14.15s 14.41s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 16.98s (± 0.35%) 16.95s (± 0.32%) -0.03s (- 0.17%) 16.82s 17.07s
Angular - node (v12.1.0, x64)
Memory used 322,762k (± 0.03%) 322,810k (± 0.03%) +48k (+ 0.01%) 322,626k 322,979k
Parse Time 1.93s (± 0.77%) 1.94s (± 0.90%) +0.01s (+ 0.36%) 1.89s 1.98s
Bind Time 0.82s (± 0.63%) 0.81s (± 0.68%) -0.01s (- 0.85%) 0.80s 0.83s
Check Time 5.11s (± 0.35%) 5.09s (± 0.23%) -0.02s (- 0.29%) 5.07s 5.12s
Emit Time 5.98s (± 0.44%) 5.98s (± 0.54%) -0.00s (- 0.02%) 5.93s 6.06s
Total Time 13.84s (± 0.28%) 13.82s (± 0.31%) -0.01s (- 0.10%) 13.74s 13.91s
Compiler-Unions - node (v12.1.0, x64)
Memory used 190,329k (± 0.15%) 190,379k (± 0.11%) +50k (+ 0.03%) 189,966k 190,910k
Parse Time 0.77s (± 1.06%) 0.77s (± 0.75%) -0.00s (- 0.39%) 0.76s 0.78s
Bind Time 0.53s (± 0.56%) 0.53s (± 0.71%) -0.00s (- 0.57%) 0.52s 0.53s
Check Time 7.02s (± 0.72%) 6.96s (± 0.55%) -0.07s (- 0.94%) 6.84s 7.04s
Emit Time 2.55s (± 1.41%) 2.57s (± 1.30%) +0.02s (+ 0.63%) 2.52s 2.65s
Total Time 10.88s (± 0.68%) 10.82s (± 0.52%) -0.06s (- 0.56%) 10.68s 10.92s
Monaco - node (v12.1.0, x64)
Memory used 325,118k (± 0.01%) 325,217k (± 0.03%) +99k (+ 0.03%) 325,029k 325,624k
Parse Time 1.53s (± 0.92%) 1.53s (± 0.49%) -0.00s (- 0.20%) 1.52s 1.55s
Bind Time 0.72s (± 0.72%) 0.72s (± 0.80%) +0.00s (+ 0.14%) 0.71s 0.73s
Check Time 5.14s (± 0.23%) 5.13s (± 0.38%) -0.01s (- 0.10%) 5.09s 5.17s
Emit Time 3.10s (± 0.94%) 3.09s (± 0.37%) -0.01s (- 0.35%) 3.07s 3.12s
Total Time 10.49s (± 0.24%) 10.47s (± 0.25%) -0.02s (- 0.18%) 10.42s 10.53s
TFS - node (v12.1.0, x64)
Memory used 288,812k (± 0.02%) 288,822k (± 0.01%) +10k (+ 0.00%) 288,707k 288,915k
Parse Time 1.21s (± 1.08%) 1.21s (± 0.43%) +0.00s (+ 0.00%) 1.20s 1.22s
Bind Time 0.69s (± 0.69%) 0.69s (± 0.75%) -0.00s (- 0.29%) 0.68s 0.70s
Check Time 4.68s (± 0.33%) 4.69s (± 0.40%) +0.01s (+ 0.21%) 4.65s 4.74s
Emit Time 3.17s (± 0.82%) 3.18s (± 0.50%) +0.01s (+ 0.25%) 3.16s 3.23s
Total Time 9.76s (± 0.41%) 9.77s (± 0.31%) +0.01s (+ 0.15%) 9.72s 9.88s
material-ui - node (v12.1.0, x64)
Memory used 444,059k (± 0.06%) 443,930k (± 0.09%) -129k (- 0.03%) 442,817k 444,424k
Parse Time 2.03s (± 0.52%) 2.03s (± 0.37%) 0.00s ( 0.00%) 2.02s 2.06s
Bind Time 0.64s (± 0.52%) 0.64s (± 1.04%) 0.00s ( 0.00%) 0.63s 0.66s
Check Time 12.96s (± 0.71%) 12.95s (± 0.66%) -0.01s (- 0.05%) 12.86s 13.21s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.63s (± 0.59%) 15.63s (± 0.54%) -0.01s (- 0.05%) 15.53s 15.89s
Angular - node (v14.15.1, x64)
Memory used 321,425k (± 0.01%) 321,423k (± 0.01%) -2k (- 0.00%) 321,365k 321,463k
Parse Time 1.93s (± 0.49%) 1.92s (± 0.48%) -0.01s (- 0.57%) 1.91s 1.95s
Bind Time 0.86s (± 0.58%) 0.86s (± 0.72%) -0.00s (- 0.46%) 0.85s 0.87s
Check Time 5.12s (± 0.59%) 5.13s (± 0.51%) +0.01s (+ 0.29%) 5.07s 5.19s
Emit Time 6.36s (± 0.81%) 6.33s (± 0.60%) -0.03s (- 0.46%) 6.28s 6.40s
Total Time 14.28s (± 0.52%) 14.25s (± 0.46%) -0.03s (- 0.18%) 14.15s 14.38s
Compiler-Unions - node (v14.15.1, x64)
Memory used 189,492k (± 0.02%) 189,494k (± 0.01%) +2k (+ 0.00%) 189,446k 189,564k
Parse Time 0.80s (± 0.72%) 0.80s (± 0.77%) -0.00s (- 0.50%) 0.79s 0.82s
Bind Time 0.56s (± 1.04%) 0.56s (± 0.65%) -0.00s (- 0.18%) 0.55s 0.56s
Check Time 7.09s (± 0.33%) 7.10s (± 0.65%) +0.01s (+ 0.13%) 7.02s 7.26s
Emit Time 2.52s (± 0.52%) 2.54s (± 0.87%) +0.02s (+ 0.79%) 2.51s 2.62s
Total Time 10.98s (± 0.32%) 11.00s (± 0.58%) +0.02s (+ 0.22%) 10.89s 11.23s
Monaco - node (v14.15.1, x64)
Memory used 324,141k (± 0.01%) 324,123k (± 0.01%) -18k (- 0.01%) 324,080k 324,197k
Parse Time 1.58s (± 0.60%) 1.56s (± 0.67%) -0.02s (- 1.26%) 1.54s 1.59s
Bind Time 0.75s (± 0.69%) 0.74s (± 0.60%) -0.01s (- 0.93%) 0.73s 0.75s
Check Time 5.12s (± 0.78%) 5.09s (± 0.45%) -0.03s (- 0.51%) 5.04s 5.14s
Emit Time 3.20s (± 0.47%) 3.17s (± 0.79%) -0.04s (- 1.12%) 3.11s 3.23s
Total Time 10.66s (± 0.51%) 10.57s (± 0.41%) -0.09s (- 0.84%) 10.47s 10.67s
TFS - node (v14.15.1, x64)
Memory used 287,753k (± 0.01%) 287,756k (± 0.01%) +3k (+ 0.00%) 287,710k 287,818k
Parse Time 1.26s (± 1.24%) 1.27s (± 0.98%) +0.01s (+ 0.47%) 1.24s 1.30s
Bind Time 0.71s (± 0.70%) 0.71s (± 0.91%) -0.00s (- 0.42%) 0.70s 0.72s
Check Time 4.69s (± 0.31%) 4.71s (± 0.57%) +0.02s (+ 0.38%) 4.67s 4.79s
Emit Time 3.26s (± 0.64%) 3.26s (± 0.65%) -0.00s (- 0.12%) 3.21s 3.29s
Total Time 9.93s (± 0.33%) 9.94s (± 0.36%) +0.01s (+ 0.13%) 9.86s 10.03s
material-ui - node (v14.15.1, x64)
Memory used 442,322k (± 0.06%) 442,430k (± 0.00%) +109k (+ 0.02%) 442,388k 442,479k
Parse Time 2.10s (± 0.67%) 2.10s (± 0.55%) -0.00s (- 0.24%) 2.07s 2.12s
Bind Time 0.70s (± 0.74%) 0.69s (± 0.71%) -0.01s (- 0.72%) 0.69s 0.71s
Check Time 13.20s (± 0.75%) 13.08s (± 0.62%) -0.12s (- 0.89%) 12.97s 13.34s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 16.00s (± 0.64%) 15.87s (± 0.49%) -0.13s (- 0.80%) 15.75s 16.13s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-206-generic
Architecturex64
Available Memory16 GB
Available Memory9 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v14.15.1, x64)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v14.15.1, x64)
  • Compiler-Unions - node (v10.16.3, x64)
  • Compiler-Unions - node (v12.1.0, x64)
  • Compiler-Unions - node (v14.15.1, x64)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v14.15.1, x64)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v14.15.1, x64)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v14.15.1, x64)
Benchmark Name Iterations
Current 43649 10
Baseline master 10

Developer Information:

Download Benchmark

@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.

@@ -12585,6 +12585,19 @@ namespace ts {
else if (grandParent.kind === SyntaxKind.TypeParameter && grandParent.parent.kind === SyntaxKind.MappedType) {
inferences = append(inferences, keyofConstraintType);
}
// When an 'infer T' declaration is the template of a mapped type, and that mapped type if the extends
Copy link
Member

@andrewbranch andrewbranch Apr 13, 2021

Choose a reason for hiding this comment

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

Suggested change
// When an 'infer T' declaration is the template of a mapped type, and that mapped type if the extends
// When an 'infer T' declaration is the template of a mapped type, and that mapped type is the extends

Comment on lines +12589 to +12590
// clause of a conditional whose check type is also a mapped type, give it the constraint of the template
// of the check type's mapped type
Copy link
Member

Choose a reason for hiding this comment

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

give it the constraint of the template of the check type's mapped type

I think this phrasing is ambiguous, and I want to nitpick it just to figure out whether I’m understanding the goal. It could be interpreted in one of two ways:

  1. Give infer T a constraint that is the constraint of the template type on the check side of the conditional type
  2. Give infer T a constraint that is the template type on the check side of the conditional type

Reading the code and the test case, I think what you mean is (2), because given

type KeysWithoutStringIndex<T> =
     { [K in keyof T]: string extends K ? never : K } extends { [_ in keyof T]: infer U }
//                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ “template of the check type’s mapped type”
     ? U
     : never

I don’t know what it means for string extends K ? never : K to have a constraint in this case, and it looks like the type you’re appending to inferences is just the type of string extends K ? never : K instantiated with Kkeyof T. Did I understand that right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes on both fronts. That constraint will then later be executed and become a single type.

const checkMappedType = (grandParent.parent as ConditionalTypeNode).checkType as MappedTypeNode;
const nodeType = getTypeFromTypeNode(checkMappedType.type!);
inferences = append(inferences, instantiateType(nodeType,
makeUnaryTypeMapper(getDeclaredTypeOfTypeParameter(getSymbolOfNode(checkMappedType.typeParameter)), checkMappedType.typeParameter.constraint ? getTypeFromTypeNode(checkMappedType.typeParameter.constraint) : keyofConstraintType)
Copy link
Member

Choose a reason for hiding this comment

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

What would it mean for checkMappedType.typeParameter.constraint to be undefined? Is that only an error condition for circular constraints?

Copy link
Member Author

Choose a reason for hiding this comment

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

So, we issue an error on it, but it's when you wrote a mapped type like {[K in]: K} - the constraint is simply missing. That's just handled gracefully here, rather than crashing.

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.

Clarifying the comment some would be helpful, but the change looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Milestone Bug PRs that fix a bug with a specific milestone
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4.2 Regression: Inferring values of object constructed from keyof T is not assignable to keyof T
3 participants