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

Ensure rest type for source parameter is readonly in relations #53258

Merged
merged 2 commits into from
Mar 20, 2023

Conversation

jakebailey
Copy link
Member

@jakebailey jakebailey commented Mar 14, 2023

Fixes #53255
See also DefinitelyTyped/DefinitelyTyped#64739

Given:

declare function each<T extends ReadonlyArray<any>>(cases: ReadonlyArray<T>): (fn: (...args: T) => any) => void;

const cases = [
    [1, '1'],
    [2, '2'],
] as const;

const eacher = each(cases);

// Error.
eacher((a, b) => {
});

// No error?
eacher((...args) => {
    const [a, b] = args;
});

We used to say:

Argument of type '(a: 1 | 2, b: "1" | "2") => void' is not assignable to parameter of type '(...args: readonly [1, "1"] | readonly [2, "2"]) => any'.
  Types of parameters 'a' and 'args' are incompatible.
    Type 'readonly [1, "1"] | readonly [2, "2"]' is not assignable to type '[a: 1 | 2, b: "1" | "2"]'.
      The type 'readonly [1, "1"]' is 'readonly' and cannot be assigned to the mutable type '[a: 1 | 2, b: "1" | "2"]'.(2345)

Here, the "source" type is [a: 1 | 2, b: "1" | "2"], but that can't be assigned to the target as the target is readonly. But, these are the rest arguments, so there's no way for this function to observe the read-only ness of the parameter. (Note: these are parameters, so directionality is swapped.)

I'm not sure if this is a perfect fix, but one way to "solve" this is to just ensure the tuple/array we cook up for the source is readonly, that way it's always compatible. This fixes the issue, but does change some error messages because they do observe the intermediary type here.

Maybe the "better" thing to do here would be to strip readonly-ness from both sourceType and targetType if they were produced via getRestTypeAtPosition? I haven't exactly found "the way" to do that yet, e.g. no helper named "remove readonly from tuple or array".

@typescript-bot typescript-bot added Author: Team For Milestone Bug PRs that fix a bug with a specific milestone labels Mar 14, 2023
@jakebailey
Copy link
Member Author

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 14, 2023

Heya @jakebailey, I've started to run the abridged perf test suite on this PR at 5f7155d. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 14, 2023

Heya @jakebailey, I've started to run the diff-based top-repos suite on this PR at 5f7155d. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 14, 2023

Heya @jakebailey, I've started to run the diff-based user code test suite on this PR at 5f7155d. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 14, 2023

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 14, 2023

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

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 14, 2023

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 14, 2023

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/149439/artifacts?artifactName=tgz&fileId=E33B7102478AE1E2DBEF19B4743FF90C23816DB6BF2A8FC73E70ED7940D0E74302&fileName=/typescript-5.1.0-insiders.20230314.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]".;

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the user test suite comparing main and refs/pull/53258/merge:

Everything looks good!

@typescript-bot
Copy link
Collaborator

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

Here they are:

Comparison Report - main..53258

Metric main 53258 Delta Best Worst p-value
Angular - node (v16.17.1, x64)
Memory used 361,467k (± 0.01%) 361,469k (± 0.01%) ~ 361,424k 361,494k p=0.687 n=6
Parse Time 3.52s (± 0.30%) 3.51s (± 0.46%) ~ 3.49s 3.53s p=0.250 n=6
Bind Time 1.17s (± 1.17%) 1.18s (± 0.54%) ~ 1.17s 1.19s p=0.654 n=6
Check Time 9.48s (± 0.68%) 9.44s (± 0.31%) ~ 9.41s 9.48s p=0.227 n=6
Emit Time 7.96s (± 1.22%) 7.93s (± 0.61%) ~ 7.89s 8.02s p=0.935 n=6
Total Time 22.14s (± 0.58%) 22.06s (± 0.22%) ~ 21.99s 22.12s p=0.296 n=6
Compiler-Unions - node (v16.17.1, x64)
Memory used 194,247k (± 0.96%) 192,516k (± 0.07%) ~ 192,282k 192,632k p=0.173 n=6
Parse Time 1.58s (± 1.91%) 1.57s (± 0.87%) ~ 1.55s 1.59s p=0.461 n=6
Bind Time 0.82s (± 0.50%) 0.82s (± 0.50%) ~ 0.81s 0.82s p=0.218 n=6
Check Time 10.03s (± 0.70%) 10.06s (± 0.36%) ~ 10.02s 10.12s p=0.421 n=6
Emit Time 2.98s (± 0.60%) 3.04s (± 4.15%) ~ 2.98s 3.30s p=0.142 n=6
Total Time 15.41s (± 0.47%) 15.49s (± 0.79%) +0.09s (+ 0.56%) 15.43s 15.74s p=0.043 n=6
Monaco - node (v16.17.1, x64)
Memory used 346,711k (± 0.00%) 346,721k (± 0.00%) ~ 346,703k 346,734k p=0.335 n=6
Parse Time 2.72s (± 0.28%) 2.73s (± 0.80%) ~ 2.71s 2.77s p=0.315 n=6
Bind Time 1.09s (± 0.47%) 1.08s (± 0.75%) ~ 1.07s 1.09s p=0.523 n=6
Check Time 7.75s (± 0.70%) 7.75s (± 0.28%) ~ 7.71s 7.77s p=0.870 n=6
Emit Time 4.46s (± 1.21%) 4.46s (± 0.90%) ~ 4.42s 4.53s p=0.871 n=6
Total Time 16.02s (± 0.59%) 16.03s (± 0.24%) ~ 15.99s 16.09s p=0.573 n=6
TFS - node (v16.17.1, x64)
Memory used 300,127k (± 0.01%) 300,140k (± 0.01%) ~ 300,115k 300,182k p=0.471 n=6
Parse Time 2.16s (± 0.45%) 2.16s (± 0.35%) ~ 2.15s 2.17s p=0.554 n=6
Bind Time 1.24s (± 1.11%) 1.24s (± 0.85%) ~ 1.22s 1.25s p=0.867 n=6
Check Time 7.19s (± 0.44%) 7.16s (± 0.65%) ~ 7.10s 7.22s p=0.261 n=6
Emit Time 4.35s (± 0.36%) 4.34s (± 0.70%) ~ 4.30s 4.38s p=0.568 n=6
Total Time 14.94s (± 0.35%) 14.89s (± 0.34%) ~ 14.80s 14.95s p=0.195 n=6
material-ui - node (v16.17.1, x64)
Memory used 477,742k (± 0.01%) 477,747k (± 0.00%) ~ 477,718k 477,776k p=0.575 n=6
Parse Time 3.22s (± 0.17%) 3.22s (± 0.47%) ~ 3.19s 3.23s p=0.498 n=6
Bind Time 0.95s (± 1.10%) 0.96s (± 0.54%) ~ 0.95s 0.96s p=0.794 n=6
Check Time 18.06s (± 0.56%) 18.19s (± 0.98%) ~ 18.03s 18.52s p=0.173 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 22.22s (± 0.49%) 22.36s (± 0.81%) ~ 22.20s 22.71s p=0.128 n=6
xstate - node (v16.17.1, x64)
Memory used 550,725k (± 0.02%) 550,740k (± 0.02%) ~ 550,631k 550,935k p=1.000 n=6
Parse Time 3.93s (± 0.37%) 3.94s (± 0.25%) ~ 3.92s 3.95s p=0.624 n=6
Bind Time 1.80s (± 0.65%) 1.78s (± 0.46%) -0.01s (- 0.83%) 1.77s 1.79s p=0.048 n=6
Check Time 3.04s (± 0.92%) 3.02s (± 0.64%) ~ 3.00s 3.05s p=0.332 n=6
Emit Time 0.09s (± 0.00%) 0.09s (± 0.00%) ~ 0.09s 0.09s p=1.000 n=6
Total Time 8.85s (± 0.35%) 8.84s (± 0.39%) ~ 8.80s 8.88s p=0.571 n=6
System
Machine Namets-ci-ubuntu
Platformlinux 5.4.0-135-generic
Architecturex64
Available Memory16 GB
Available Memory15 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v16.17.1, x64)
Scenarios
  • Angular - node (v16.17.1, x64)
  • Compiler-Unions - node (v16.17.1, x64)
  • Monaco - node (v16.17.1, x64)
  • TFS - node (v16.17.1, x64)
  • material-ui - node (v16.17.1, x64)
  • xstate - node (v16.17.1, x64)
Benchmark Name Iterations
Current 53258 6
Baseline main 6

Developer Information:

Download Benchmark

@typescript-bot
Copy link
Collaborator

Hey @jakebailey, it looks like the DT test run failed. Please check the log for more details.
You can check the log here.

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the top-repos suite comparing main and refs/pull/53258/merge:

Everything looks good!

Copy link
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

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

Since this doesn't change applyToParameterTypes, this doesn't change inference, so won't be observable to a Parameters conditional call - you'll only see the difference in relationship error messages bewteen signatures. And maybe that's OK. It's s little weird to say that variadic rests are sometimes-readonly-sometimes-not, but... function parameters are pretty wonky on the edges as-is.

@jakebailey
Copy link
Member Author

Yeah, this is just a case where inference is already right (the insides don't change).

Would my alternative suggestion of stripping readonly from rest types work better, if I can find the way to do that?

@jakebailey
Copy link
Member Author

In general, I'm also having trouble seeing where anyone would ever want the result of Parameters to be readonly itself; it never matters what you pass into a function, the actual variadic parameters themselves are copied, so only individual parameters need to maintain readonly-ness (e.g. arrays).

@jakebailey
Copy link
Member Author

jakebailey commented Mar 15, 2023

Actually, I'm even more weirded out, because in my example above args is readonly [1, '1'] | readonly [2, '2'], but clearly mutating it will not mutate the input...

> const fn = (...args) => { args[0] = "oops" }
undefined
> const arr = ["some", "values"]
undefined
> fn(...arr)
undefined
> arr
[ 'some', 'values' ]

So, shouldn't we be stripping readonly in every case from rest arrays? That seems like the right fix...

@jakebailey jakebailey marked this pull request as draft March 15, 2023 23:21
@jakebailey
Copy link
Member Author

I mean, maybe I guess this fix is okay just to get rid of the spurious relation error, and something that addresses my followup comments can come later?

@jakebailey jakebailey marked this pull request as ready for review March 15, 2023 23:28
@jakebailey
Copy link
Member Author

@typescript-bot run dt

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 15, 2023

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

Update: The results are in!

@typescript-bot
Copy link
Collaborator

Hey @jakebailey, it looks like the DT test run failed. Please check the log for more details.
You can check the log here.

@weswigham
Copy link
Member

I mean, maybe I guess this fix is okay just to get rid of the spurious relation error, and something that addresses my followup comments can come later?

Seems reasonable.

@jakebailey
Copy link
Member Author

Followup is here: #53398

@jakebailey jakebailey merged commit e9836a4 into microsoft:main Mar 20, 2023
@jakebailey jakebailey deleted the fix-53255 branch March 20, 2023 23:18
@sandersn
Copy link
Member

sandersn commented Mar 23, 2023

Breaks ckeditor__ckeditor5-upload on DT. Didn't notice it until today because the overnight tests were blocked by the --legacy-peer-deps problem.

Filed #53459 with a 5-line, 2-type repro.

@jakebailey
Copy link
Member Author

My fault for not retrying DT until I saw the results...

This pull request was closed.
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.

Parameters created from tuple are treated as mutable instead of immutable, unless written as "...args"
4 participants