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

Infer type arguments on instance check #58028

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

molisani
Copy link
Contributor

@molisani molisani commented Apr 1, 2024

Fixes #17473 - Infer constrained generic parameters after instanceof check
Fixes #46668 - Private field check narrows generic class too far

This is an updated and ready-to-be-reviewed recreation of my previous #49863. Please see that PR for a longer description of the problem and the proposed solution, as I don't want to duplicate it all here unnecessarily. In short, when instantiating the type of a class for an instance check, TypeScript would populate all type arguments with any no matter the constraint on the type parameter or the strictness settings. This change factors in the compiler strictness as well as the constraints and variances of the type parameters to "infer" the type arguments.

This does NOT handle #57317, per @Andarist on #57323 but I have included that test case here as these changes do introduce new behavior to that case (any to unknown). I can remove if it feels irrelevant to these changes.

Breaking Changes

From the last PR, I have resolved to use the compiler option strictInstanceOfTypeParameters to gate these otherwise breaking changes. However, there was some discussion about the possibility of not hiding these changes behind a compiler option. I can test enabling these changes for all, similar to what I did last time.

@molisani molisani force-pushed the strict-instance-of-type-parameters branch from 9b2769e to 49747b0 Compare April 1, 2024 21:30
@typescript-bot
Copy link
Collaborator

Looks like you're introducing a change to the public API surface area. If this includes breaking changes, please document them on our wiki's API Breaking Changes page.

Also, please make sure @DanielRosenwasser and @RyanCavanaugh are aware of the changes, just as a heads up.

@typescript-bot typescript-bot added the For Milestone Bug PRs that fix a bug with a specific milestone label Apr 1, 2024
@typescript-bot
Copy link
Collaborator

The TypeScript team hasn't accepted the linked issue #17473. If you can get it accepted, this PR will have a better chance of being reviewed.

1 similar comment
@typescript-bot
Copy link
Collaborator

The TypeScript team hasn't accepted the linked issue #17473. If you can get it accepted, this PR will have a better chance of being reviewed.

@jakebailey
Copy link
Member

@typescript-bot test it

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 2, 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 comparing main and refs/pull/58028/merge:

Something interesting changed - please have a look.

Details

puppeteer

packages/puppeteer-core/tsconfig.json

type-fest

tsconfig.json

  • [NEW] error TS2417: Class static side 'typeof Building' incorrectly extends base class static side '{ prototype: Pick<BuildingType, keyof BuildingType>; }'.

@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
Angular - node (v18.15.0, x64)
Memory used 295,704k (± 0.01%) 295,730k (± 0.01%) ~ 295,709k 295,764k p=0.093 n=6
Parse Time 2.66s (± 0.15%) 2.64s (± 0.34%) -0.02s (- 0.69%) 2.63s 2.65s p=0.006 n=6
Bind Time 0.84s (± 0.90%) 0.83s (± 0.49%) ~ 0.83s 0.84s p=0.100 n=6
Check Time 8.24s (± 0.35%) 8.25s (± 0.31%) ~ 8.20s 8.28s p=0.570 n=6
Emit Time 7.04s (± 0.17%) 7.04s (± 0.40%) ~ 7.02s 7.08s p=0.870 n=6
Total Time 18.76s (± 0.17%) 18.76s (± 0.30%) ~ 18.68s 18.85s p=0.936 n=6
Compiler-Unions - node (v18.15.0, x64)
Memory used 193,284k (± 0.93%) 192,703k (± 0.74%) ~ 192,070k 195,619k p=0.689 n=6
Parse Time 1.36s (± 0.86%) 1.37s (± 0.89%) ~ 1.35s 1.38s p=0.507 n=6
Bind Time 0.73s (± 0.56%) 0.73s (± 0.56%) ~ 0.72s 0.73s p=1.000 n=6
Check Time 9.52s (± 0.20%) 9.54s (± 0.37%) ~ 9.48s 9.59s p=0.090 n=6
Emit Time 2.63s (± 0.75%) 2.63s (± 0.56%) ~ 2.60s 2.64s p=1.000 n=6
Total Time 14.23s (± 0.13%) 14.26s (± 0.38%) ~ 14.16s 14.32s p=0.063 n=6
Monaco - node (v18.15.0, x64)
Memory used 347,408k (± 0.01%) 347,418k (± 0.01%) ~ 347,390k 347,446k p=0.470 n=6
Parse Time 2.48s (± 0.40%) 2.48s (± 0.40%) ~ 2.47s 2.49s p=1.000 n=6
Bind Time 0.93s (± 0.44%) 0.93s (± 0.44%) ~ 0.92s 0.93s p=1.000 n=6
Check Time 7.02s (± 0.30%) 7.03s (± 0.39%) ~ 6.99s 7.07s p=0.329 n=6
Emit Time 4.06s (± 0.20%) 4.06s (± 0.27%) ~ 4.04s 4.07s p=0.448 n=6
Total Time 14.48s (± 0.16%) 14.50s (± 0.17%) ~ 14.48s 14.55s p=0.165 n=6
TFS - node (v18.15.0, x64)
Memory used 302,767k (± 0.01%) 302,789k (± 0.01%) ~ 302,751k 302,821k p=0.171 n=6
Parse Time 2.40s (± 0.83%) 2.39s (± 0.67%) ~ 2.36s 2.40s p=0.193 n=6
Bind Time 1.19s (± 0.34%) 1.19s (± 0.00%) ~ 1.19s 1.19s p=0.405 n=6
Check Time 7.50s (± 0.31%) 7.52s (± 0.20%) ~ 7.50s 7.54s p=0.256 n=6
Emit Time 4.25s (± 0.84%) 4.28s (± 0.40%) ~ 4.25s 4.30s p=0.257 n=6
Total Time 15.34s (± 0.14%) 15.38s (± 0.15%) ~ 15.35s 15.40s p=0.072 n=6
material-ui - node (v18.15.0, x64)
Memory used 510,199k (± 0.01%) 510,160k (± 0.01%) ~ 510,115k 510,249k p=0.229 n=6
Parse Time 3.92s (± 0.13%) 3.94s (± 0.44%) ~ 3.92s 3.97s p=0.051 n=6
Bind Time 1.46s (± 1.14%) 1.46s (± 0.52%) ~ 1.45s 1.47s p=1.000 n=6
Check Time 25.50s (± 0.64%) 25.45s (± 0.47%) ~ 25.30s 25.57s p=0.687 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 30.88s (± 0.52%) 30.85s (± 0.37%) ~ 30.71s 30.97s p=1.000 n=6
mui-docs - node (v18.15.0, x64)
Memory used 1,745,032k (± 0.00%) 1,745,037k (± 0.00%) ~ 1,744,985k 1,745,076k p=0.689 n=6
Parse Time 6.61s (± 0.82%) 6.64s (± 0.93%) ~ 6.58s 6.74s p=0.572 n=6
Bind Time 2.37s (± 0.79%) 2.37s (± 0.82%) ~ 2.34s 2.39s p=0.870 n=6
Check Time 56.67s (± 0.46%) 56.78s (± 0.32%) ~ 56.64s 57.13s p=0.575 n=6
Emit Time 0.13s (± 3.87%) 0.13s (± 3.87%) ~ 0.13s 0.14s p=1.000 n=6
Total Time 65.78s (± 0.42%) 65.93s (± 0.24%) ~ 65.78s 66.24s p=0.261 n=6
self-build-src - node (v18.15.0, x64)
Memory used 2,400,790k (± 0.03%) 2,400,711k (± 0.03%) ~ 2,399,987k 2,401,858k p=0.810 n=6
Parse Time 6.07s (± 0.54%) 6.04s (± 1.19%) ~ 5.95s 6.13s p=0.810 n=6
Bind Time 2.25s (± 1.51%) 2.26s (± 0.92%) ~ 2.23s 2.29s p=0.810 n=6
Check Time 39.98s (± 0.25%) 40.02s (± 0.62%) ~ 39.84s 40.48s p=0.471 n=6
Emit Time 3.15s (± 0.68%) 3.17s (± 1.00%) ~ 3.11s 3.20s p=0.196 n=6
Total Time 51.47s (± 0.16%) 51.51s (± 0.64%) ~ 51.22s 52.07s p=0.471 n=6
self-compiler - node (v18.15.0, x64)
Memory used 416,189k (± 0.00%) 416,323k (± 0.01%) +134k (+ 0.03%) 416,302k 416,356k p=0.005 n=6
Parse Time 3.35s (± 0.58%) 3.36s (± 0.95%) ~ 3.33s 3.42s p=0.627 n=6
Bind Time 1.30s (± 0.90%) 1.31s (± 0.96%) ~ 1.30s 1.33s p=0.278 n=6
Check Time 18.23s (± 0.28%) 18.19s (± 0.29%) ~ 18.12s 18.26s p=0.261 n=6
Emit Time 1.34s (± 2.03%) 1.35s (± 1.58%) ~ 1.32s 1.37s p=0.627 n=6
Total Time 24.22s (± 0.27%) 24.21s (± 0.17%) ~ 24.14s 24.26s p=0.872 n=6
vscode - node (v18.15.0, x64)
Memory used 2,898,944k (± 0.00%) 2,899,520k (± 0.00%) +576k (+ 0.02%) 2,899,329k 2,899,637k p=0.005 n=6
Parse Time 12.91s (± 0.11%) 12.97s (± 0.54%) ~ 12.90s 13.07s p=0.462 n=6
Bind Time 4.14s (± 0.54%) 4.14s (± 0.37%) ~ 4.11s 4.15s p=0.505 n=6
Check Time 72.13s (± 0.56%) 71.99s (± 0.83%) ~ 71.47s 73.12s p=0.336 n=6
Emit Time 20.10s (± 8.33%) 20.00s (± 7.87%) ~ 19.29s 23.21s p=0.422 n=6
Total Time 109.29s (± 1.83%) 109.09s (± 1.98%) ~ 107.93s 113.46s p=0.378 n=6
webpack - node (v18.15.0, x64)
Memory used 408,878k (± 0.01%) 409,310k (± 0.01%) +433k (+ 0.11%) 409,244k 409,399k p=0.005 n=6
Parse Time 3.87s (± 0.34%) 3.87s (± 0.48%) ~ 3.85s 3.90s p=1.000 n=6
Bind Time 1.68s (± 0.69%) 1.69s (± 0.61%) ~ 1.67s 1.70s p=0.491 n=6
Check Time 16.80s (± 0.36%) 16.85s (± 0.24%) ~ 16.80s 16.91s p=0.091 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 22.35s (± 0.29%) 22.41s (± 0.18%) ~ 22.36s 22.48s p=0.149 n=6
xstate - node (v18.15.0, x64)
Memory used 513,462k (± 0.01%) 513,501k (± 0.02%) ~ 513,365k 513,659k p=0.230 n=6
Parse Time 3.98s (± 0.61%) 3.97s (± 0.33%) ~ 3.95s 3.98s p=0.744 n=6
Bind Time 1.88s (± 1.46%) 1.89s (± 1.60%) ~ 1.85s 1.93s p=0.745 n=6
Check Time 3.44s (± 0.66%) 3.45s (± 1.28%) ~ 3.39s 3.50s p=0.808 n=6
Emit Time 0.09s (± 5.95%) 0.08s (± 4.99%) ~ 0.08s 0.09s p=0.112 n=6
Total Time 9.38s (± 0.50%) 9.39s (± 0.72%) ~ 9.31s 9.47s p=0.520 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Angular - node (v18.15.0, x64)
  • Compiler-Unions - node (v18.15.0, x64)
  • Monaco - node (v18.15.0, x64)
  • TFS - node (v18.15.0, x64)
  • material-ui - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate - 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 comparing main and refs/pull/58028/merge:

Something interesting changed - please have a look.

Details

apollographql/apollo-client

1 of 12 projects failed to build with the old tsc and were ignored

tsconfig.json

src/tsconfig.json

colinhacks/zod

tsconfig.json

  • error TS2345: Argument of type 'any[]' is not assignable to parameter of type '[] | [ZodTypeAny, ...ZodTypeAny[]]'.
  • error TS2322: Type 'unknown' is not assignable to type 'Primitive'.

configs/tsconfig.types.json

  • error TS2345: Argument of type 'any[]' is not assignable to parameter of type '[] | [ZodTypeAny, ...ZodTypeAny[]]'.
  • error TS2322: Type 'unknown' is not assignable to type 'Primitive'.

configs/tsconfig.test.json

  • error TS2345: Argument of type 'any[]' is not assignable to parameter of type '[] | [ZodTypeAny, ...ZodTypeAny[]]'.
  • error TS2322: Type 'unknown' is not assignable to type 'Primitive'.

configs/tsconfig.esm.json

  • error TS2345: Argument of type 'any[]' is not assignable to parameter of type '[] | [ZodTypeAny, ...ZodTypeAny[]]'.
  • error TS2322: Type 'unknown' is not assignable to type 'Primitive'.

configs/tsconfig.cjs.json

  • error TS2345: Argument of type 'any[]' is not assignable to parameter of type '[] | [ZodTypeAny, ...ZodTypeAny[]]'.
  • error TS2322: Type 'unknown' is not assignable to type 'Primitive'.

desktop/desktop

1 of 4 projects failed to build with the old tsc and were ignored

tsconfig.json

google/blockly

2 of 3 projects failed to build with the old tsc and were ignored

tsconfig.json

graphile/crystal

7 of 10 projects failed to build with the old tsc and were ignored

utils/lru/__tests__/tsconfig.json

honojs/hono

3 of 5 projects failed to build with the old tsc and were ignored

tsconfig.json

tsconfig.build.json

jquense/yup

1 of 2 projects failed to build with the old tsc and were ignored

tsconfig.json

  • error TS2322: Type '{ <U extends unknown>(enums: readonly (Reference<unknown> | U)[], message?: Message<{ values: any; }> | undefined): Schema<unknown, unknown, unknown, Flags>; (enums: readonly unknown[], message: Message<{ values: any; }>): any; }' is not assignable to type '{ <U extends any>(enums: readonly (Reference<unknown> | U)[], message?: Message<{ values: any; }> | undefined): Schema<any, any, any, "">; (enums: readonly any[], message: Message<{ values: any; }>): any; }'.
  • error TS2322: Type '<U extends unknown>(enums: readonly (Reference<unknown> | Maybe<U>)[], message?: Message<{ values: any; }>) => Schema<unknown, unknown, unknown, Flags>' is not assignable to type '<U extends any>(enums: readonly (Reference<unknown> | Maybe<U>)[], message?: Message<{ values: any; }>) => Schema<any, any, any, "">'.

microsoft/vscode

4 of 54 projects failed to build with the old tsc and were ignored

src/tsconfig.tsec.json

src/tsconfig.monaco.json

src/tsconfig.json

neoclide/coc.nvim

tsconfig.json

ReactiveX/rxjs

13 of 16 projects failed to build with the old tsc and were ignored

packages/observable/tsconfig.json

  • error TS2345: Argument of type 'Subscriber<T> | (Partial<Observer<T>> & Subscriber<never>) | (((value: T) => void) & Subscriber<never>)' is not assignable to parameter of type 'Subscriber<T>'.

sindresorhus/got

tsconfig.json

sindresorhus/type-fest

tsconfig.json

  • error TS2417: Class static side 'typeof Building' incorrectly extends base class static side '{ prototype: Pick<BuildingType, keyof BuildingType>; }'.

theatre-js/theatre

16 of 24 projects failed to build with the old tsc and were ignored

packages/dataverse-experiments/tsconfig.json

@fatcerberus
Copy link

Wow, it broke approximately everything 😅

@jakebailey
Copy link
Member

Not surprising if you've seen #49863.

Notably, this new PR adds a strict mode setting. That's what made DT clean, as DT does not set strict=true, but rather enables specific strict mode options. (Been on my todo list to look into change that for a while.)

@molisani
Copy link
Contributor Author

molisani commented Apr 2, 2024

@jakebailey If you pack this I can make playground reproductions of some of these errors.

And let me know if you want to test turning it on by default 😅

@jakebailey
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 2, 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 Apr 2, 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/160908/artifacts?artifactName=tgz&fileId=887091D6EC182401D9A7B148E7615E05FC9A1E5F8637C385DC2D7778C222C73C02&fileName=/typescript-5.5.0-insiders.20240402.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]".;

@molisani
Copy link
Contributor Author

molisani commented Apr 2, 2024

There are a decent number of errors where some type that was any is now unknown. Most of these could be fixed by adding/modifying a constraint or adding a type cast. The strangest errors showed up when prototype was used/declared manually. I've compiled a collection of some errors that weren't clear to me on first glance:

A) Extracting prototype directly is now too restrictive

From: google/blockly
Playground - This code used Pick<typeof Class, "prototype"> as a shorthand to capture the prototype, but this is now the most restrictive version. In order to loosen the type, it needs to be manually declared with whatever type argument is most correct.

B) new.target.prototype doesn't capture local type parameters

From: google/blockly
Playground - This is now a valid error, as there is no guarantee that every instance of this class has a type argument that matches DEFAULT_VALUE.

C) Subclass doesn't share instance of type in manual prototype declaration

From: sindresorhus/type-fest
Playground - I'm not exactly sure why this is going wrong. It seems like the concern about it being a different subtype is not warranted, but I can't say for sure. This one is definitely the most worrying of what I've seen, as I wouldn't expect class X extends Y {} to give me an error.

@molisani molisani force-pushed the strict-instance-of-type-parameters branch from 49747b0 to fcab6eb Compare April 25, 2024 15:39
@molisani molisani force-pushed the strict-instance-of-type-parameters branch from fcab6eb to 26df4e9 Compare May 1, 2024 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Milestone Bug PRs that fix a bug with a specific milestone
Projects
Status: Waiting on reviewers
5 participants