Skip to content

fix(compiler-cli): disallow template access to private members of base classes - #71053

Draft
JeanMeche wants to merge 1 commit into
angular:mainfrom
JeanMeche:fix-71032-parent-private-access
Draft

JeanMeche wants to merge 1 commit into
angular:mainfrom
JeanMeche:fix-71032-parent-private-access

Conversation

@JeanMeche

Copy link
Copy Markdown
Member

Previously, TS2341 diagnostics in type check blocks were suppressed whenever the accessed property was preceded by this. or (this).. While this allowed templates and host bindings to access private members declared on their own component or directive class (introduced in #70188), it also inadvertently suppressed TS2341 when accessing private members inherited from a base class or narrowed subtype, and failed to handle parenthesized, non-null asserted, or optional-chained this receivers.

This commit inspects the AST node and symbol declarations via ts.TypeChecker when handling TS2341 diagnostics so that private member access is only permitted on this when all private declarations of the accessed property belong to the host component or directive class itself.

Fixes #71032

@angular-robot angular-robot Bot added the area: compiler Issues related to `ngc`, Angular's template compiler label Sep 29, 2026
@ngbot ngbot Bot added this to the Backlog milestone Sep 29, 2026
…e classes

Previously, TS2341 diagnostics in type check blocks were suppressed whenever
the accessed property was preceded by `this.` or `(this).`. While this allowed
templates and host bindings to access private members declared on their own
component or directive class, it also inadvertently suppressed TS2341 when
accessing private members inherited from a base class or narrowed subtype, and
failed to handle parenthesized, non-null asserted, or optional-chained `this`
receivers.

Inspect the AST node and symbol declarations via `ts.TypeChecker` when handling
TS2341 diagnostics so that private member access is only permitted on `this`
when all private declarations of the accessed property belong to the host
component or directive class itself.

Fixes angular#71032
@JeanMeche
JeanMeche force-pushed the fix-71032-parent-private-access branch from 7b59010 to 15f795e Compare September 29, 2026 18:10
@kaplan81

Copy link
Copy Markdown

Hey @JeanMeche, thanks for jumping on #71032!

I had a look at the diff and did some digging, but compiler internals aren't really my thing, so I might be off on some of this. A few things I'm wondering about:

  1. this['_name']: this never raises TS2341 (see @mauriziocescon's example in Access to TypeScript private members in templates consequences #70514), so a child template could still reach a parent's private members that way. Is that fine to leave as-is?
  2. TS 7.1 API: I found getSymbolAtLocation and getTypeOfSymbol there, but nothing like ts.getCombinedModifierFlags. And since nodes would be references into the Go process, I'm guessing the includes(declaringClass) comparison wouldn't work anymore. Would this need a different approach there?
  3. Cost: if I got feat(compiler): allow template to access private props #70188 right, every template read of an own private member produces a TS2341 that then gets filtered out. So this check runs on each of those reads, and over the interop API that means a few round trips every time. Is that a concern?
  4. Other tools: the blog says the *.ngtypecheck.ts output is meant for other tools too. Would those tools report the TS2341 errors that Angular filters out?

Sorry for commenting on a Draft PR, specially if this has been covered already.

@wartab

wartab commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

@kaplan81

kaplan81 commented Oct 1, 2026 •

Copy link
Copy Markdown

https://www.typescriptlang.org/play/?#code/MYGwhgzhAECC0G8BQ1XQA4CcCWA3MALgKbQQD2AtkQQBbYB2A5tALzQCMA3EgL5JLAy9CAWhhW0ekQDucABQBKbgKHkQRAHQgyjOWADaAInJVaDRoYC6SlcLLqtOvRpPU6TJUA

Access to private members via ["member"] is a TypeScript thing, unrelated to Angular.

@wartab you are absolutely right but don't you think that Angular, to some extend, is TypeScript? It has always been written on TypeScript at its core and compiled using a superset of the TypeScript compiler.

So everything that has an impact on TypeScript is also our business, IMHO.

@JeanMeche

Copy link
Copy Markdown
Member Author

What he is saying is that, this is how TS work, so Angular works the same way. Indexed access has always allowed to access private props and probably always will.

@kaplan81

kaplan81 commented Oct 1, 2026

Copy link
Copy Markdown

Fair enough, makes sense: bracket access is standard TS behavior, so it's out of scope here. Sorry for the mix-up!

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

Labels

area: compiler Issues related to `ngc`, Angular's template compiler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Child template can access his parent private members that the child class cannot

3 participants