Skip to content

Defer checking subexpressions of binary expressions with known boolean result type#60865

Closed
Andarist wants to merge 4 commits intomicrosoft:mainfrom
Andarist:defer-checking-binary-subexpressions
Closed

Defer checking subexpressions of binary expressions with known boolean result type#60865
Andarist wants to merge 4 commits intomicrosoft:mainfrom
Andarist:defer-checking-binary-subexpressions

Conversation

@Andarist
Copy link
Copy Markdown
Contributor

@Andarist Andarist commented Dec 28, 2024

fixes #60130
fixes #62279

This PR removes the mechanism introduced in #54380 in favor of using the older checkDeferredNode mechanism that allows the compiler to avoid an extra set of redundant errors.

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Dec 28, 2024
// Those boolean arguments wouldn't even have to be viable sources for type arguments being inferred.
//
// For those reasons, we defer obtaining the operand types here and checking the related errors.
checkNodeDeferred(node);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is really the core of the fix. The rest of the PR only moves code around (for the most part)

state.skip = true;
setLastResult(state, booleanType);
break;
case SyntaxKind.QuestionQuestionToken:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Out of curiosity (this may be a dumb question): Since SyntaxKind.EqualsToken (which I assume refers to assignment) is handled above and SyntaxKind.QuestionQuestionToken is handled here, should nullish coalescing assignment (SyntaxKind.QuestionQuestionEqualsToken) also be handled here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's a valid question. I think no adjustments have to be made here though. Only = is permitted when the left side is a destructuring pattern. Other kinds of assignment~ operators in such scenarios result in a syntax error:

let a: number | undefined;
({ a } ??= { a: 10 }); // Uncaught SyntaxError: Invalid left-hand side in assignment

Copilot AI review requested due to automatic review settings August 14, 2025 19:37
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the TypeScript compiler's handling of binary expressions with known boolean result types by removing a recently added mechanism in favor of the older checkDeferredNode approach. The change aims to reduce redundant type checking errors, particularly in control flow analysis scenarios where binary expressions like comparisons have predetermined boolean types.

  • Removes the CheckMode.TypeOnly flag mechanism introduced in a previous PR
  • Switches to using checkDeferredNode for binary expressions with boolean results
  • Adds specific handling for comparison and equality operators to defer type checking until later

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

File Description
src/compiler/types.ts Adds NullishCoalesceExpression interface for type safety
src/compiler/checker.ts Major refactoring of binary expression checking, removes CheckMode.TypeOnly, adds deferred checking for boolean operators
Test files Adds new test cases for control flow inference and updates existing baselines
Comments suppressed due to low confidence (3)

@Andarist Andarist force-pushed the defer-checking-binary-subexpressions branch from d0ce498 to 5abe12a Compare December 11, 2025 13:52
@typescript-bot
Copy link
Copy Markdown
Collaborator

With 6.0 out as the final release vehicle for this codebase, we're closing all PRs that don't fit the merge criteria for post-6.0 patches. If you think this was a mistake and this PR fits the post-6.0 patch criteria, please post to the 6.0 iteration issue with details (specifically, which PR and which patch criteria it satisfies).

Next steps for PRs:

  • For crash bugfixes or language service improvements, PRs are currently accepted at the typescript-go repo
  • Changes to type system behavior should wait until after 7.0, at which point mainline TypeScript development will resume in this repository with the Go codebase
  • Library file updates (lib.d.ts etc) continue to live in this repo or the DOM Generator repo as appropriate

@github-project-automation github-project-automation bot moved this from Not started to Done in PR Backlog Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

For Backlog Bug PRs that fix a backlog bug

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Assertion signature on generics doesn't narrow Type inference fails when type narrowing occurs within a loop

5 participants