AOT Compiler requires public properties, while non-AOT allows private properties
See original GitHub issueI’m submitting a … (check one with “x”)
[X] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
When writing a component, fields referred inside a template is allowed to be declared private
and it will still work.
However, such private
fields generate errors with the AOT compiler. They must be turned public
.
Expected behavior Be consistent. Either allow or not allow.
Reproduction of the problem
template: "<div>{{hello}}</div>"
class someModule {
private hello: string; <-- doesn't work with AOT compiler
}
Please tell us about your environment: Windows 10.
- Angular version: 2.0.0
- Browser: all
- Language: TypeScript
- Node (for AoT issues):
node --version
= v4.3.1
Issue Analytics
- State:
- Created 7 years ago
- Reactions:30
- Comments:51 (19 by maintainers)
Top Results From Across the Web
Angular 6 private methods - Stack Overflow
Why AOT Compiler requires public properties, while non-AOT allows private properties? With JIT we convert all the code to ES5 and then at ......
Read more >Angular and TypeScript Private Properties. | by Vikash Singh
Why AOT Compiler requires public properties, while non-AOT allows private properties? With JIT we convert all the code to ES5 and then at ......
Read more >Ahead-of-time (AOT) compilation - Angular
The compiler can only reference exported symbols. Decorated component class members must be public. You cannot make an @Input() property private or protected....
Read more >Angular Aot Build Failing Because Of Private Member - ADocLib
Solvedangular AOT Compiler requires public properties while nonAOT allows private [X] bug report search github for a similar issue or PR before.
Read more >Ahead-of-Time Compilation in Angular - Minko Gechev
When the compilation takes place? ... This allows the JavaScript virtual machine to perform property access caching and execute the change ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@aluanhaddad you have a big misunderstanding in here. There is no subset of Typescript in here. No one said that.
By using JiT (AKA the common way of doing Angular 2 since day 1), you transpile your code to ES5 to run it in the browser. Say you have:
That will generate, more or less something like:
Notice how
FooComponent()
contains aname
property. It doesn’t matter whether you putpublic
orprivate
atname
because in ES5 that concept does not exist so you end with the same code.When Angular runs that code, it will say. Ok, I have this html code, this template with a
{{name}}
and I can see athis.name
in the ES5 code with a value, let’s grab that and display it.So far, so good.
So why do we have
private
andpublic
if at the end the ES5 will not care? Well, the typescript compiler (and your editor) will complain if you try to access a private variable from where you can’t do that:Your editor will tell you that you cannot access
bar
andtsc
(typescript compiler) will give you an error because you are trying to access a private variable.Back in the component example,
tsc
doesn’t complain because at compile time, no one tries to access thatname
field and the template will do the databinding at runtime where your code is not typescript anymore but ES5 and again, no visibility modifier in there.That being said, with AoT, we sort of “convert” the template code to Typescript itself (again, Typescript, not any subset). Imagine the previous component, it will generate something like this:
This is typescript code and it is our template converted to typescript code.
Here we create our
div
and a “placeholder” for a binding (AKA{{name}}
).A bit later we do:
We are accessing the
name
property fromcontext
where context is ourFooComponent
.Then we do:
We get that placeholder from before and we assign to it the value of
name
AKAHello
.Having this in mind,
name
has to be public, because if you set it private,this.context.name
will raise an error sincename
is private and you cannot access it from outside the class.So as TL;DR; there is no typescript subset. With JiT we convert all the code to ES5 and then in runtime we do the bindings. All the visibility modifiers are lost in that process, so it doesn’t matter if you say public or private for that.
On the other hand, with AoT, we generate some typescript code for our templates, that will try to access those fields. If they are private, they simply cannot access those properties, hence, we have to put them as public.
@achimha All of this only applies to template <-> component interaction. A template is not part of the component class, so a template can only access to public properties from the component.
On the other hand, when we inject stuff using DI, we can use private because we only use that injected object within the component class and never in the template. That being said, if there is any use case where you need to inject something that needs to be used in the template, yes, you need public as well, but so far, that is not the case in any doc example.
@robwormald Since a lot of official angular documentation uses
private
, isn’t this a massive pit of failure for developers new to TypeScript? Considering that a component class is conceptually a cohesive unit, anyone not understanding thatprivate
properties are not private at runtime will have no intuition as to why their code no longer works under AOT.While I am not of fan of the TypeScript’s
private
keyword, because it is somewhat misleading, it sounds like JIT compiled components are working precisely because privacy is not enforced at runtime.I would suggest removing the visibility modifiers on properties during AOT transformations and changing
private
topublic
for constructor parameter properties.Edit: This issue should be re-opened