Skip to content

fix(language-service): show narrowed type for @let declarations in hover#66836

Closed
TejasSathe010 wants to merge 1 commit intoangular:mainfrom
TejasSathe010:fix/language-service-let-narrowing-hover
Closed

fix(language-service): show narrowed type for @let declarations in hover#66836
TejasSathe010 wants to merge 1 commit intoangular:mainfrom
TejasSathe010:fix/language-service-let-narrowing-hover

Conversation

@TejasSathe010
Copy link
Copy Markdown

When hovering over a @let declaration variable inside a control flow block (e.g., @if), the Language Service now shows the flow-narrowed type instead of the original declaration type.

The fix retrieves type information from the TCB at the usage location where TypeScript has applied flow narrowing, rather than from the declaration location.

Fixes #65491

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.dev application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

When hovering over a @let variable inside a narrowed scope (e.g., @if (obj !== null)), the Language Service shows the original declaration type including null.

Issue Number: #65491

What is the new behavior?

The hover tooltip now shows the flow-narrowed type, matching what the Angular compiler uses for type checking.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Issue reported on: Angular v19.2.5 with Language Service Extension v20.1.1
Validated on: Angular main branch (21.1.0-next.1)

Root cause: getQuickInfoForLetDeclarationSymbol() queried TypeScript at the declaration location in the TCB, not the usage location where flow narrowing applies.

Fix: Added getTcbLocationOfNode() to TemplateTypeChecker to find the TCB node at the usage site. Updated QuickInfoBuilder to use this method for @let declarations, with graceful fallback to the original behavior. This follows the same pattern used by getQuickInfoForBindingSymbol and getQuickInfoForPipeSymbol.

When hovering over a `@let` declaration variable inside a control flow
block (e.g., `@if`), the Language Service now shows the flow-narrowed
type instead of the original declaration type.

The fix retrieves type information from the TCB at the usage location
where TypeScript has applied flow narrowing, rather than from the
declaration location.

Fixes angular#65491
@google-cla
Copy link
Copy Markdown

google-cla bot commented Jan 29, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@pullapprove pullapprove bot requested a review from devversion January 29, 2026 21:34
@angular-robot angular-robot bot added the area: language-service Issues related to Angular's VS Code language service label Jan 29, 2026
@ngbot ngbot bot added this to the Backlog milestone Jan 29, 2026
@google-cla google-cla bot added cla: yes and removed cla: no labels Jan 30, 2026

import {LanguageServiceTestEnv, Project} from '../testing';

describe('let declarations narrowing', () => {
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 be in the quick info suite not its own file

* Gets the TCB location for a template node at its usage site.
* This is useful for getting flow-narrowed types for variables.
*/
getTcbLocation(node: AST | TmplAstNode): TcbLocation | null {
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.

the tcbLocation should probably be on the LetDeclarationSymbol when constructed rather than having to grab it later. e.g.

  /**
   * The location in the TCB where this symbol is used or declared.
   * For a declaration, this matches `localVarLocation`.
   * For a usage, this is the location of the node usage in the TCB.
   */
  tcbLocation: TcbLocation;

I would guess this is also an issue with ReferenceSymbol and VariableSymbol for references (<div #IAmARef) and varaibles (*ngFor variables)?

@atscott atscott closed this Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: language-service Issues related to Angular's VS Code language service cla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tooltip hints for template variables do not match compiler type when narrowed by template syntax

3 participants