Skip to content

Private members used only in the template are reported as unused (TS6133) #71093

Description

@aminesbdev

Which @angular/* package(s) are the source of the bug?

compiler-cli, language-service

Is this a regression?

No

Description

Since #70188 (22.2.0), a template can read private members of its component. TypeScript doesn't see those reads though, so a private member that is only used in the template is still reported as unused (TS6133).

import {Component, signal} from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <p>{{ privateTitle() }}</p>
    <p>{{ protectedTitle() }}</p>
  `,
})
export class App {
  private readonly privateTitle = signal('private member');
  protected readonly protectedTitle = signal('protected member');
}

With "noUnusedLocals": true in tsconfig.json, ng build fails:

✘ [ERROR] TS6133: 'privateTitle' is declared but its value is never read. [plugin angular-compiler]

    src/app.ts:12:19:
      12 │   private readonly privateTitle = signal('private member');
         ╵                    ~~~~~~~~~~~~

ng serve fails the same way on startup.

Without noUnusedLocals the build passes, but the editor still greys out privateTitle and offers the "Remove unused declaration for: 'privateTitle'" quick fix, which breaks the template when applied. The Angular language service forwards TypeScript's suggestion diagnostics as is, so having the extension installed doesn't change this.

protectedTitle isn't reported in either case, since TypeScript doesn't track unused protected members.

I'd expect a private member read by the component's own template to count as used, both in the build and in the editor. Whatever the fix, private members that are genuinely unused should still be reported, since that's what noUnusedLocals is for.

This came up in #70514 (comment), opening a separate issue so it can be tracked on its own.

Please provide a link to a minimal reproduction of the bug

The component above, with "noUnusedLocals": true in tsconfig.json.

Please provide the exception or error you saw

TS6133: 'privateTitle' is declared but its value is never read.

Please provide the environment you discovered this bug in (run ng version)

Angular CLI       : 22.2.0
Angular           : 22.2.0
Node.js           : 24.21.0
Package Manager   : npm 11.19.0
Operating System  : darwin arm64

┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package                   │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build            │ 22.2.0            │ 22.2.0            │
│ @angular/cli              │ 22.2.0            │ 22.2.0            │
│ @angular/common           │ 22.2.0            │ 22.2.0            │
│ @angular/compiler         │ 22.2.0            │ 22.2.0            │
│ @angular/compiler-cli     │ 22.2.0            │ 22.2.0            │
│ @angular/core             │ 22.2.0            │ 22.2.0            │
│ @angular/platform-browser │ 22.2.0            │ 22.2.0            │
│ rxjs                      │ 7.8.2             │ ~7.8.0            │
│ typescript                │ 6.0.3             │ ~6.0.2            │
└───────────────────────────┴───────────────────┴───────────────────┘

Anything else?

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: compilerIssues related to `ngc`, Angular's template compilergemini-triagedLabel noting that an issue has been triaged by gemini

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions