Skip to content

Check for strict subtypes and then regular subtypes in getNarrowedType - #52984

Merged
Anders Hejlsberg (ahejlsberg) merged 7 commits into
mainfrom
fix52827
Mar 3, 2023
Merged

Check for strict subtypes and then regular subtypes in getNarrowedType#52984
Anders Hejlsberg (ahejlsberg) merged 7 commits into
mainfrom
fix52827

Conversation

@ahejlsberg

@ahejlsbergAnders Hejlsberg (ahejlsberg) commented Feb 26, 2023

Copy link
Copy Markdown
Member

Experiment to see the effects of first checking for strict subtypes and then checking for regular subtypes in getNarrowedType, and picking the asserted type only when it is a pure subtype of the original type.

First experiment checked only using the strict subtype relationship, but that introduces too many breaking changes (specifically caused by strict checking of signature arity and readonly properties).

Fixes#52827.

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the extended test suite on this PR at 0325f9d. You can monitor the build here.

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the diff-based user code test suite on this PR at 0325f9d. You can monitor the build here.

Update: The results are in!

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at 0325f9d. You can monitor the build here.

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the diff-based top-repos suite on this PR at 0325f9d. You can monitor the build here.

Update: The results are in!

@typescript-bot

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg) Here are the results of running the user test suite comparing main and refs/pull/52984/merge:

Everything looks good!

@typescript-bot

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've run the RWC suite on this PR - assuming you're on the TS core team, you can view the resulting diff here.

@jakebailey

Copy link
Copy Markdown
Member

TypeScript Bot (@typescript-bot) perf test this faster

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Jake Bailey (@jakebailey), I've started to run the abridged perf test suite on this PR at 0325f9d. You can monitor the build here.

Update: The results are in!

@typescript-bot

Copy link
Copy Markdown
Contributor

Jake Bailey (@jakebailey)
The results of the perf run you requested are in!

Here they are:

Comparison Report - main..52984

Metricmain52984DeltaBestWorstp-value
Angular - node (v16.17.1, x64)
Memory used359,065k (± 0.00%)359,052k (± 0.00%)~359,035k359,078kp=0.173 n=6
Parse Time3.71s (± 0.41%)3.71s (± 0.43%)~3.70s3.74sp=0.801 n=6
Bind Time1.19s (± 0.34%)1.19s (± 0.53%)~1.18s1.20sp=0.673 n=6
Check Time9.45s (± 0.72%)9.45s (± 0.51%)~9.37s9.51sp=0.935 n=6
Emit Time7.92s (± 0.56%)7.94s (± 0.58%)~7.88s8.01sp=0.332 n=6
Total Time22.27s (± 0.40%)22.29s (± 0.37%)~22.18s22.43sp=0.936 n=6
Compiler-Unions - node (v16.17.1, x64)
Memory used191,378k (± 0.05%)191,871k (± 0.66%)~191,275k194,463kp=0.936 n=6
Parse Time1.58s (± 1.11%)1.56s (± 0.78%)-0.02s (- 1.27%)1.54s1.57sp=0.046 n=6
Bind Time0.82s (± 0.00%)0.82s (± 0.50%)~0.81s0.82sp=0.405 n=6
Check Time10.10s (± 0.32%)10.01s (± 0.55%)-0.09s (- 0.89%)9.94s10.07sp=0.013 n=6
Emit Time3.00s (± 0.69%)3.01s (± 0.35%)~2.99s3.02sp=0.564 n=6
Total Time15.49s (± 0.34%)15.39s (± 0.41%)-0.10s (- 0.63%)15.30s15.45sp=0.029 n=6
Monaco - node (v16.17.1, x64)
Memory used343,133k (± 0.00%)343,125k (± 0.00%)~343,098k343,138kp=0.470 n=6
Parse Time2.79s (± 0.49%)2.79s (± 0.48%)~2.77s2.80sp=0.388 n=6
Bind Time1.09s (± 1.51%)1.08s (± 0.48%)~1.08s1.09sp=0.794 n=6
Check Time7.69s (± 0.25%)7.70s (± 0.57%)~7.64s7.76sp=0.625 n=6
Emit Time4.45s (± 0.87%)4.46s (± 0.76%)~4.43s4.52sp=0.686 n=6
Total Time16.01s (± 0.37%)16.02s (± 0.20%)~15.98s16.06sp=0.747 n=6
TFS - node (v16.17.1, x64)
Memory used299,242k (± 0.01%)299,244k (± 0.01%)~299,208k299,261kp=0.873 n=6
Parse Time2.16s (± 0.82%)2.16s (± 0.48%)~2.15s2.18sp=0.410 n=6
Bind Time1.24s (± 1.22%)1.24s (± 0.99%)~1.22s1.25sp=0.801 n=6
Check Time7.18s (± 0.41%)7.17s (± 0.53%)~7.12s7.22sp=0.809 n=6
Emit Time4.34s (± 0.80%)4.32s (± 0.66%)~4.29s4.35sp=0.295 n=6
Total Time14.91s (± 0.49%)14.89s (± 0.47%)~14.79s14.99sp=0.568 n=6
material-ui - node (v16.17.1, x64)
Memory used475,653k (± 0.01%)475,686k (± 0.01%)~475,634k475,779kp=0.230 n=6
Parse Time3.29s (± 0.23%)3.28s (± 0.31%)~3.27s3.30sp=0.351 n=6
Bind Time0.96s (± 0.43%)0.96s (± 0.54%)~0.95s0.96sp=0.595 n=6
Check Time17.96s (± 0.49%)17.98s (± 0.39%)~17.92s18.11sp=0.572 n=6
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)~0.00s0.00sp=1.000 n=6
Total Time22.21s (± 0.41%)22.22s (± 0.31%)~22.15s22.35sp=0.683 n=6
xstate - node (v16.17.1, x64)
Memory used545,824k (± 0.03%)545,946k (± 0.04%)~545,745k546,256kp=0.378 n=6
Parse Time4.29s (± 0.35%)4.29s (± 0.55%)~4.25s4.32sp=1.000 n=6
Bind Time1.76s (± 0.43%)1.76s (± 0.29%)~1.75s1.76sp=0.784 n=6
Check Time2.99s (± 0.37%)2.99s (± 0.58%)~2.96s3.01sp=0.222 n=6
Emit Time0.09s (± 0.00%)0.09s (± 0.00%)~0.09s0.09sp=1.000 n=6
Total Time9.12s (± 0.18%)9.12s (± 0.27%)~9.09s9.16sp=0.808 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)
BenchmarkNameIterations
Current529846
Baselinemain6

Developer Information:

Download Benchmark

@typescript-bot

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg) Here are the results of running the top-repos suite comparing main and refs/pull/52984/merge:

Something interesting changed - please have a look.

Details

microsoft/vscode

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

src/tsconfig.tsec.json

@ahejlsbergAnders Hejlsberg (ahejlsberg) changed the title Use strictSubtypeRelation in getNarrowedType and narrow only for pure subtypesUse for strict subtypes and then regular subtypes in getNarrowedTypeFeb 26, 2023
@ahejlsbergAnders Hejlsberg (ahejlsberg) changed the title Use for strict subtypes and then regular subtypes in getNarrowedTypeCheck for strict subtypes and then regular subtypes in getNarrowedTypeFeb 26, 2023
@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the diff-based top-repos suite on this PR at d737eee. You can monitor the build here.

Update: The results are in!

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the extended test suite on this PR at d737eee. You can monitor the build here.

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the diff-based user code test suite on this PR at d737eee. You can monitor the build here.

Update: The results are in!

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the abridged perf test suite on this PR at d737eee. You can monitor the build here.

Update: The results are in!

@typescript-bot

TypeScript Bot (typescript-bot) commented Feb 26, 2023

Copy link
Copy Markdown
Contributor

Heya Anders Hejlsberg (@ahejlsberg), I've started to run the parallelized Definitely Typed test suite on this PR at d737eee. You can monitor the build here.

@typescript-bot

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg) Here are the results of running the user test suite comparing main and refs/pull/52984/merge:

Everything looks good!

@typescript-bot

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg)
The results of the perf run you requested are in!

Here they are:

Comparison Report - main..52984

Metricmain52984DeltaBestWorstp-value
Angular - node (v16.17.1, x64)
Memory used359,065k (± 0.00%)359,068k (± 0.01%)~359,016k359,092kp=0.575 n=6
Parse Time3.71s (± 0.41%)3.71s (± 0.22%)~3.70s3.72sp=0.555 n=6
Bind Time1.19s (± 0.34%)1.19s (± 0.53%)~1.18s1.20sp=0.673 n=6
Check Time9.45s (± 0.72%)9.45s (± 0.27%)~9.40s9.47sp=0.324 n=6
Emit Time7.92s (± 0.56%)7.92s (± 0.52%)~7.86s7.96sp=1.000 n=6
Total Time22.27s (± 0.40%)22.26s (± 0.20%)~22.21s22.33sp=0.872 n=6
Compiler-Unions - node (v16.17.1, x64)
Memory used191,378k (± 0.05%)192,851k (± 0.53%)+1,472k (+ 0.77%)192,379k194,951kp=0.005 n=6
Parse Time1.58s (± 1.11%)1.55s (± 0.97%)-0.02s (- 1.48%)1.54s1.58sp=0.042 n=6
Bind Time0.82s (± 0.00%)0.82s (± 0.00%)~0.82s0.82sp=1.000 n=6
Check Time10.10s (± 0.32%)10.13s (± 0.67%)~10.01s10.22sp=0.077 n=6
Emit Time3.00s (± 0.69%)2.99s (± 0.80%)~2.95s3.02sp=0.739 n=6
Total Time15.49s (± 0.34%)15.50s (± 0.47%)~15.38s15.59sp=0.748 n=6
Monaco - node (v16.17.1, x64)
Memory used343,133k (± 0.00%)343,135k (± 0.00%)~343,109k343,145kp=0.810 n=6
Parse Time2.79s (± 0.49%)2.80s (± 0.43%)~2.78s2.81sp=0.191 n=6
Bind Time1.09s (± 1.51%)1.08s (± 0.38%)~1.07s1.08sp=0.245 n=6
Check Time7.69s (± 0.25%)7.67s (± 0.45%)~7.63s7.70sp=0.323 n=6
Emit Time4.45s (± 0.87%)4.42s (± 0.42%)~4.39s4.44sp=0.329 n=6
Total Time16.01s (± 0.37%)15.96s (± 0.34%)~15.89s16.03sp=0.228 n=6
TFS - node (v16.17.1, x64)
Memory used299,242k (± 0.01%)299,254k (± 0.01%)~299,230k299,292kp=0.810 n=6
Parse Time2.16s (± 0.82%)2.15s (± 0.62%)~2.13s2.16sp=0.498 n=6
Bind Time1.24s (± 1.22%)1.25s (± 0.44%)~1.24s1.25sp=0.342 n=6
Check Time7.18s (± 0.41%)7.16s (± 0.56%)~7.11s7.20sp=0.332 n=6
Emit Time4.34s (± 0.80%)4.34s (± 0.99%)~4.30s4.42sp=0.686 n=6
Total Time14.91s (± 0.49%)14.89s (± 0.49%)~14.82s15.02sp=0.518 n=6
material-ui - node (v16.17.1, x64)
Memory used475,653k (± 0.01%)475,667k (± 0.01%)~475,616k475,756kp=0.378 n=6
Parse Time3.29s (± 0.23%)3.28s (± 0.46%)~3.27s3.31sp=0.318 n=6
Bind Time0.96s (± 0.43%)0.96s (± 0.66%)~0.95s0.97sp=0.673 n=6
Check Time17.96s (± 0.49%)18.08s (± 0.41%)~17.96s18.18sp=0.064 n=6
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)~0.00s0.00sp=1.000 n=6
Total Time22.21s (± 0.41%)22.32s (± 0.35%)~22.19s22.41sp=0.078 n=6
xstate - node (v16.17.1, x64)
Memory used545,824k (± 0.03%)545,834k (± 0.01%)~545,769k545,963kp=0.810 n=6
Parse Time4.29s (± 0.35%)4.29s (± 0.37%)~4.26s4.30sp=0.808 n=6
Bind Time1.76s (± 0.43%)1.76s (± 0.36%)~1.75s1.77sp=0.718 n=6
Check Time2.99s (± 0.37%)3.00s (± 0.45%)~2.99s3.03sp=0.067 n=6
Emit Time0.09s (± 0.00%)0.09s (± 0.00%)~0.09s0.09sp=1.000 n=6
Total Time9.12s (± 0.18%)9.14s (± 0.22%)~9.12s9.17sp=0.225 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)
BenchmarkNameIterations
Current529846
Baselinemain6

Developer Information:

Download Benchmark

@typescript-bot

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg) Here are the results of running the top-repos suite comparing main and refs/pull/52984/merge:

Everything looks good!

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

Jake Bailey (@jakebailey) You can see some of them here.

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

I think we should consider bringing this one into 5.0.

@MichaelMitchell-at

michaelm (MichaelMitchell-at) commented Mar 3, 2023

Copy link
Copy Markdown
Contributor

I think we should consider bringing this one into 5.0.

Original reporter of #50916 here. I tried out #52282 again in our codebase and while it does address the original issue, it introduced a regression elsewhere so this would still block us from upgrading to TS 5.0. I've tried out the fix in this PR locally and it seems to resolve both issues, so it'd be great if this could make it into TS 5.0.

The new regression if curious

typeDistributedKeyOf<T>=Textendsunknown ? keyofT : never;typeNarrowByKeyValue<ObjT,KeyTextendsPropertyKey,ValueT>=ObjTextendsunknown
? KeyTextendskeyofObjT
? ValueTextendsObjT[KeyT]
? ObjT&Readonly<Record<KeyT,ValueT>>
: never
: never
: never;typeNarrowByDeepValue<ObjT,DeepPathT,ValueT>=DeepPathTextendsreadonly[
infer HeadextendsDistributedKeyOf<ObjT>,]
? NarrowByKeyValue<ObjT,Head,ValueT>
: DeepPathTextendsreadonly[infer HeadextendsDistributedKeyOf<ObjT>, ...infer Rest]
? NarrowByKeyValue<ObjT,Head,NarrowByDeepValue<NonNullable<ObjT[Head]>,Rest,ValueT>>
: never;declarefunctiondoesValueAtDeepPathSatisfy<ObjTextendsobject,constDeepPathTextendsReadonlyArray<number|string>,ValueT,>(obj: ObjT,deepPath: DeepPathT,predicate: (arg: unknown)=>arg is ValueT,): obj is NarrowByDeepValue<ObjT,DeepPathT,ValueT>;typeFoo={value: {type: 'A'};a?: number}|{value: {type: 'B'};b?: number};declarefunctionisA(arg: unknown): arg is 'A';declarefunctionisB(arg: unknown): arg is 'B';declarefunctionassert(condition: boolean): asserts condition;functiontest1(foo: Foo): {value: {type: 'A'};a?: number}{assert(doesValueAtDeepPathSatisfy(foo,['value','type'],isA));returnfoo;}functiontest2(foo: Foo): {value: {type: 'A'};a?: number}{assert(!doesValueAtDeepPathSatisfy(foo,['value','type'],isB));returnfoo;}

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

michaelm (@MichaelMitchell-at) Good to hear this PR fixes the issues. Meanwhile, would you mind updating the regression code above with the definitions of the missing functions so we can have an additional repro.

@MichaelMitchell-at

Copy link
Copy Markdown
Contributor

michaelm (@MichaelMitchell-at) Good to hear this PR fixes the issues. Meanwhile, would you mind updating the regression code above with the definitions of the missing functions so we can have an additional repro.

Ok, I'll need to refactor a bit to remove some internal dependencies

@chriskrycho

Copy link
Copy Markdown

This also fixes a regression in Ember's internal type test suite for TS 5.1 (no issue on 5.0) shaped like this:

functionexample(vals: Array<unknown>|MyCollection<unknown>): number{if(Array.isArray(vals)){returnvals.length;// ^^^^ has type `Array<any>`}else{// ❌ type error (erroneous!)returnvals.collectionSize;// ^^^^ has type `Array<unknown> | MyCollection<unknown>`}}

With this PR, this is back to behaving the way it did in v5.0 and earlier. 👍🏼

@MichaelMitchell-at

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg) updated

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

michaelm (@MichaelMitchell-at) Much appreciated. Will add as a test case.

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

Chris Krycho (@chriskrycho) I take it you mean this PR brings it back to behaving like 4.9 and earlier, right?

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

Additional repro added in latest commit.

@chriskrycho

Chris Krycho (chriskrycho) commented Mar 3, 2023

Copy link
Copy Markdown

Anders Hejlsberg (@ahejlsberg) Possibly I missed up my bisection, but in my testing, I thought I confirmed that the 5.0 RC worked and 5.1 did not. I can dig further (though not till Monday at the earliest).

@jakebailey

Copy link
Copy Markdown
Member

TypeScript Bot (@typescript-bot) cherry-pick this to release-5.0

@typescript-bot

TypeScript Bot (typescript-bot) commented Mar 3, 2023

Copy link
Copy Markdown
Contributor

Heya Jake Bailey (@jakebailey), I've started to run the task to cherry-pick this into release-5.0 on this PR at 8bb30e2. You can monitor the build here.

@typescript-bot

Copy link
Copy Markdown
Contributor

Hey Jake Bailey (@jakebailey), I've opened #53085 for you.

TypeScript Bot (typescript-bot) pushed a commit to typescript-bot/TypeScript that referenced this pull request Mar 4, 2023
Component commits:
b3d3ec9 Use strictSubtypeRelation in getNarrowedType and narrow only for pure subtypes
0325f9d Accept new baselines
3df807f First check for strict subtypes, then check for regular subtypes
d737eee Accept new baselines
9b2d602 Add tests
9ea8a55 Accept new baselines
8bb30e2 Add another repro
Daniel Rosenwasser (DanielRosenwasser) pushed a commit that referenced this pull request Mar 7, 2023
…e-5.0 (#53085)
Co-authored-by: Anders Hejlsberg <andersh@microsoft.com>
@microsoftMicrosoft (microsoft) locked as resolved and limited conversation to collaborators Oct 22, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Author: TeamFor Milestone BugPRs that fix a bug with a specific milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improvement to getNarrowedType changes lodash's isArray

6 participants

@ahejlsberg@typescript-bot@jakebailey@Andarist@MichaelMitchell-at@chriskrycho