Skip to content

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

@zoltanium

Description

@zoltanium

🐞 bug report

Is this a regression?

Unsure.

Description

Tooltip type hints can end up in a mismatch with the compiler when using template logic to narrow types.

Example:

component.ts:

protected source$!: Observable<DataItem>;

In the below example, the tooltip for obj within the <div> tag will be marked as nullable (see Screenshot 1)

component.html:

@let obj= source$ | async;
@if (obj !== null) {
  <div [id]="obj.data" />
}

Whereas in the below example, the tooltip correctly recognizes the type as non-nullable (see Screenshot 2):

component.html:

@let nullableObj = source$ | async;
@if (nullableObj !== null) {
  @let obj = nullableObj;
  <div [id]="obj.data"></div>
}

Note: The compiled type is read properly by ngtsc for nullability rules. This report only applies to the tooltip.

Bug Type

What does this bug affect

  • [x ] Angular Language Service VSCode extension
  • Angular Language Service server

Reproduction

Steps to reproduce the behavior:

  1. Create a nullable property on a component
  2. Use @let to assign a template variable to that component's value
  3. Use @if to narrow the type to non-nullable
  4. Reference the template variable within the @if block
  5. Observe | null even though variable is non-nullable within block

Expected behavior

The tooltip should match the compiler-determined type at point of reference, rather than reading only the initial assignment - this is the assumed behavior on the Typescript side, and the bug makes it difficult to use the extension for debugging certain nullability scenarios.

Logs

Screenshots

1:

Image

2:

Image

🌍 Your Environment

Angular Version:




     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 19.2.6
Node: 22.16.0
Package Manager: pnpm 10.12.3
OS: win32 x64

Angular: 19.2.5
... animations, common, compiler, compiler-cli, core, forms
... localize, platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1902.6
@angular-devkit/build-angular   19.2.6
@angular-devkit/core            19.2.6
@angular-devkit/schematics      19.2.6
@angular/cdk                    19.2.8
@angular/cli                    19.2.6
@schematics/angular             19.2.6
rxjs                            7.8.2
typescript                      5.8.3
zone.js                         0.15.0


Extension Version:



v20.1.1 

VSCode Version:



Version: 1.101.2 (user setup)
Commit: 2901c5ac6db8a986a5666c3af51ff804d05af0d4
Date: 2025-06-24T20:27:15.391Z
Electron: 35.5.1
ElectronBuildId: 11727614
Chromium: 134.0.6998.205
Node.js: 22.15.1
V8: 13.4.114.21-electron.0
OS: Windows_NT x64 10.0.22631

Operating System:



OS Name	Microsoft Windows 11 Business
Version	10.0.22631 Build 22631

Extension options:





Anything else relevant?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions