Skip to content

Add Support for Using Aliased Discriminants in Conditional Statements - #56173

Merged
gabritto merged 3 commits into
microsoft:mainfrom
Zzzen:aliased-discriminants
Nov 8, 2023
Merged

Add Support for Using Aliased Discriminants in Conditional Statements#56173
gabritto merged 3 commits into
microsoft:mainfrom
Zzzen:aliased-discriminants

Conversation

@Zzzen

Copy link
Copy Markdown
Contributor

Fixes#55577

@typescript-bottypescript-bot added the For Backlog Bug PRs that fix a backlog bug label Oct 22, 2023
@Zzzen
Zzzenforce-pushed the aliased-discriminants branch from 2d7c54b to c914ebfCompareOctober 22, 2023 15:42
Comment threadsrc/compiler/checker.ts Outdated
Comment on lines +27163 to +27165
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
return isVariableDeclaration(node.parent) && isVarConstLike(node.parent);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

shouldn't this lead to calling isConstantReference recursively (perhaps accompanied by some other checks but still)? What about nested binding patterns (const { a: { b: b2 } } = ...)?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Thank you for bringing this to my attention! I was surprised to discover that TypeScript currently lacks support for nested binding patterns during cross symbol analysis. I don't know if it is intended though.

playground

typeNested={type: 'string';resp: {data: string}}|{type: 'number';resp: {data: number;}}{letresp!: Nested;const{resp: { data }, type }=resp;if(type==='string'){datasatisfiesstring;// should not error}if(resp.type==='string'){resp.resp.datasatisfiesstring;}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This sounds like #38839 (comment)

I was more thinking about cases like this:

typeNested=|{resp: {type: "string";data: string;};}|{resp: {type: "number";data: number;};};declareconstnested: Nested;const{resp: { type, data },}=nested;if(type==="string"){datasatisfiesstring;// should be OK}

This keeps the dependency between the discriminant and another property "at the same level" but at the same time both are coming from a nested binding pattern.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think that I might have accidentally fixed this in this PR. When I sat down to it I totally forgot about the conversation here 😅

Comment threadsrc/compiler/checker.ts Outdated
return isConstantReference((node as AccessExpression).expression) && isReadonlySymbol(getNodeLinks(node).resolvedSymbol || unknownSymbol);
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
return isBindingElement(node.parent) ? isConstantReference(node.parent.parent) : isVariableDeclaration(node.parent) && isVarConstLike(node.parent);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

an alternative solution for this could look smth like this:

Suggested change
returnisBindingElement(node.parent) ? isConstantReference(node.parent.parent) : isVariableDeclaration(node.parent)&&isVarConstLike(node.parent);
constrootDeclaration=getRootDeclaration(node.parent);
returnisVariableDeclaration(rootDeclaration)&&isVarConstLike(rootDeclaration);

@AndaristAndaristNov 5, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe that this should work as well: TS playground but the problem is that we are dealing with a pseudo-reference here. At this point, we can't easily check if the original symbol for which we are performing the narrowing is a non-reassigned parameter.

This could easily be seen as a separate issue though. I only mention it here since I was touching the nearby code and I noticed this now.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Wish there was a 'const' modifier available for parameters and we could just check that!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should make that possible: #56313

@gabritto

This comment was marked as duplicate.

@gabritto

Copy link
Copy Markdown
Member

@typescript-bot run DT
@typescript-bot user test this
@typescript-bot test top100
@typescript-bot perf test this

@typescript-bot

typescript-bot commented Nov 8, 2023

Copy link
Copy Markdown
Contributor

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

Update: The results are in!

@typescript-bot

typescript-bot commented Nov 8, 2023

Copy link
Copy Markdown
Contributor

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

Update: The results are in!

@typescript-bot

typescript-bot commented Nov 8, 2023

Copy link
Copy Markdown
Contributor

Heya @gabritto, I've started to run the regular perf test suite on this PR at 9ff723c. You can monitor the build here.

Update: The results are in!

@typescript-bot

typescript-bot commented Nov 8, 2023

Copy link
Copy Markdown
Contributor

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

Update: The results are in!

@typescript-bot

Copy link
Copy Markdown
Contributor

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

There were infrastructure failures potentially unrelated to your change:

  • 3 instances of "Package install failed"

Otherwise...

Everything looks good!

@typescript-bot

Copy link
Copy Markdown
Contributor

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

Here they are:

Compiler

Comparison Report - baseline..pr
MetricbaselineprDeltaBestWorstp-value
Angular - node (v18.15.0, x64)
Memory used295,159k (± 0.01%)295,154k (± 0.01%)~295,109k295,212kp=0.748 n=6
Parse Time2.63s (± 0.34%)2.63s (± 0.56%)~2.61s2.65sp=0.804 n=6
Bind Time0.83s (± 1.00%)0.83s (± 1.00%)~0.83s0.85sp=1.000 n=6
Check Time8.04s (± 0.42%)8.05s (± 0.32%)~8.03s8.09sp=0.258 n=6
Emit Time7.08s (± 0.39%)7.09s (± 0.24%)~7.07s7.12sp=0.256 n=6
Total Time18.58s (± 0.28%)18.61s (± 0.23%)~18.56s18.67sp=0.172 n=6
Compiler-Unions - node (v18.15.0, x64)
Memory used194,600k (± 1.56%)191,675k (± 1.24%)~190,671k196,523kp=0.298 n=6
Parse Time1.36s (± 1.21%)1.35s (± 1.19%)~1.32s1.37sp=0.864 n=6
Bind Time0.73s (± 0.00%)0.73s (± 0.56%)~0.73s0.74sp=0.405 n=6
Check Time9.18s (± 0.27%)9.15s (± 0.35%)~9.09s9.18sp=0.073 n=6
Emit Time2.63s (± 0.65%)2.63s (± 0.42%)~2.62s2.65sp=1.000 n=6
Total Time13.90s (± 0.28%)13.87s (± 0.23%)~13.82s13.90sp=0.294 n=6
Monaco - node (v18.15.0, x64)
Memory used347,353k (± 0.01%)347,355k (± 0.00%)~347,337k347,381kp=1.000 n=6
Parse Time2.46s (± 0.21%)2.47s (± 0.42%)~2.45s2.48sp=0.077 n=6
Bind Time0.95s (± 0.86%)0.94s (± 0.43%)~0.94s0.95sp=0.248 n=6
Check Time6.91s (± 0.30%)6.92s (± 0.22%)~6.89s6.93sp=0.732 n=6
Emit Time4.04s (± 0.19%)4.05s (± 0.48%)~4.03s4.08sp=0.249 n=6
Total Time14.35s (± 0.15%)14.38s (± 0.13%)+0.03s (+ 0.21%)14.35s14.40sp=0.036 n=6
TFS - node (v18.15.0, x64)
Memory used302,593k (± 0.00%)302,609k (± 0.01%)~302,580k302,653kp=0.378 n=6
Parse Time1.99s (± 0.69%)2.00s (± 1.16%)~1.98s2.04sp=0.871 n=6
Bind Time1.00s (± 0.89%)1.01s (± 1.16%)~0.99s1.02sp=0.214 n=6
Check Time6.24s (± 0.41%)6.25s (± 0.26%)~6.24s6.28sp=0.678 n=6
Emit Time3.58s (± 0.73%)3.57s (± 0.49%)~3.55s3.60sp=0.870 n=6
Total Time12.81s (± 0.23%)12.84s (± 0.28%)~12.79s12.89sp=0.293 n=6
material-ui - node (v18.15.0, x64)
Memory used470,530k (± 0.00%)470,557k (± 0.01%)~470,520k470,610kp=0.128 n=6
Parse Time2.57s (± 0.53%)2.56s (± 0.33%)~2.55s2.57sp=0.210 n=6
Bind Time0.98s (± 0.56%)0.99s (± 1.89%)~0.96s1.01sp=0.676 n=6
Check Time16.62s (± 0.33%)16.62s (± 0.21%)~16.58s16.66sp=0.809 n=6
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)~0.00s0.00sp=1.000 n=6
Total Time20.18s (± 0.31%)20.18s (± 0.25%)~20.13s20.24sp=0.936 n=6
xstate - node (v18.15.0, x64)
Memory used512,830k (± 0.01%)512,822k (± 0.01%)~512,759k512,903kp=0.936 n=6
Parse Time3.27s (± 0.16%)3.27s (± 0.36%)~3.25s3.28sp=0.929 n=6
Bind Time1.54s (± 0.33%)1.54s (± 0.49%)~1.53s1.55sp=0.784 n=6
Check Time2.85s (± 0.48%)2.85s (± 0.53%)~2.82s2.86sp=0.462 n=6
Emit Time0.08s (± 0.00%)0.08s (± 0.00%)~0.08s0.08sp=1.000 n=6
Total Time7.75s (± 0.10%)7.74s (± 0.24%)~7.71s7.76sp=0.867 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)
  • xstate - node (v18.15.0, x64)
BenchmarkNameIterations
Currentpr6
Baselinebaseline6

tsserver

Comparison Report - baseline..pr
MetricbaselineprDeltaBestWorstp-value
Compiler-UnionsTSServer - node (v18.15.0, x64)
Req 1 - updateOpen2,389ms (± 0.67%)2,386ms (± 0.84%)~2,351ms2,411msp=1.000 n=6
Req 2 - geterr5,390ms (± 1.40%)5,335ms (± 1.16%)~5,296ms5,460msp=0.092 n=6
Req 3 - references325ms (± 0.75%)328ms (± 1.23%)~324ms335msp=0.250 n=6
Req 4 - navto276ms (± 1.26%)279ms (± 0.70%)~275ms281msp=0.263 n=6
Req 5 - completionInfo count1,356 (± 0.00%)1,356 (± 0.00%)~1,3561,356p=1.000 n=6
Req 5 - completionInfo85ms (± 5.15%)79ms (± 7.49%)~75ms90msp=0.099 n=6
CompilerTSServer - node (v18.15.0, x64)
Req 1 - updateOpen2,503ms (± 0.79%)2,497ms (± 0.83%)~2,476ms2,524msp=0.873 n=6
Req 2 - geterr4,066ms (± 1.31%)4,060ms (± 1.56%)~4,021ms4,188msp=0.298 n=6
Req 3 - references343ms (± 1.30%)342ms (± 1.38%)~333ms345msp=0.803 n=6
Req 4 - navto283ms (± 0.29%)282ms (± 0.43%)~280ms283msp=0.599 n=6
Req 5 - completionInfo count1,518 (± 0.00%)1,518 (± 0.00%)~1,5181,518p=1.000 n=6
Req 5 - completionInfo88ms (± 5.03%)88ms (± 5.01%)~79ms90msp=1.000 n=6
xstateTSServer - node (v18.15.0, x64)
Req 1 - updateOpen2,589ms (± 0.44%)2,597ms (± 0.44%)~2,588ms2,617msp=0.128 n=6
Req 2 - geterr1,702ms (± 2.94%)1,727ms (± 2.08%)~1,678ms1,772msp=0.378 n=6
Req 3 - references113ms (± 9.21%)112ms (±10.41%)~101ms124msp=0.627 n=6
Req 4 - navto367ms (± 0.57%)366ms (± 0.56%)~364ms368msp=0.673 n=6
Req 5 - completionInfo count2,073 (± 0.00%)2,073 (± 0.00%)~2,0732,073p=1.000 n=6
Req 5 - completionInfo310ms (± 1.83%)309ms (± 2.09%)~298ms315msp=1.000 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • CompilerTSServer - node (v18.15.0, x64)
  • Compiler-UnionsTSServer - node (v18.15.0, x64)
  • xstateTSServer - node (v18.15.0, x64)
BenchmarkNameIterations
Currentpr6
Baselinebaseline6

Startup

Comparison Report - baseline..pr
MetricbaselineprDeltaBestWorstp-value
tsc-startup - node (v18.15.0, x64)
Execution time152.75ms (± 0.21%)152.56ms (± 0.19%)-0.20ms (- 0.13%)151.38ms155.44msp=0.000 n=600
tsserver-startup - node (v18.15.0, x64)
Execution time227.90ms (± 0.14%)227.79ms (± 0.15%)-0.11ms (- 0.05%)226.18ms231.75msp=0.000 n=600
tsserverlibrary-startup - node (v18.15.0, x64)
Execution time229.11ms (± 0.16%)229.06ms (± 0.18%)-0.05ms (- 0.02%)227.58ms235.55msp=0.035 n=600
typescript-startup - node (v18.15.0, x64)
Execution time229.65ms (± 0.16%)229.00ms (± 0.24%)-0.65ms (- 0.28%)227.37ms236.03msp=0.000 n=600
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • tsc-startup - node (v18.15.0, x64)
  • tsserver-startup - node (v18.15.0, x64)
  • tsserverlibrary-startup - node (v18.15.0, x64)
  • typescript-startup - node (v18.15.0, x64)
BenchmarkNameIterations
Currentpr6
Baselinebaseline6

Developer Information:

Download Benchmarks

@typescript-bot

Copy link
Copy Markdown
Contributor

Hey @gabritto, the results of running the DT tests are ready.
Everything looks the same!
You can check the log here.

@typescript-bot

Copy link
Copy Markdown
Contributor

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

Everything looks good!

@gabritto
gabritto merged commit 7b96c28 into microsoft:mainNov 8, 2023
@microsoftmicrosoft locked as resolved and limited conversation to collaborators Oct 16, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

For Backlog BugPRs that fix a backlog bug

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Type inference fails when using combined boolean variable in if condition

5 participants

@Zzzen@gabritto@typescript-bot@Andarist@sandersn