-
Notifications
You must be signed in to change notification settings - Fork 26.4k
Description
[ ] bug report => search github for a similar issue or PR before submitting
[x] 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
Currently, the AOT compiler is very strict and requires every object involved in DI / metadata to resolve to a symbol that the AOT compiler can work with.
It is so strict that in some scenarios, even though the symbol information is not required, it will still fail (#12631, #13138)
It makes it difficult to write custom decorators to angular component or classes that are @Injectable
It is clear why all items in providers
must resolve to a known symbol, but custom decorators for a @Component
class can fail even though it's not important.
It also creates coupling between the compiler and the core. In general it must know about every runtime generated object even if the type is known in design time (via generic).
To solve this, the compiler workaround is to import core and register a bypass to all core
decorators
this._registerDecoratorOrConstructor(this.findDeclaration(diDecorators, 'Host'), Host);
this._registerDecoratorOrConstructor(
this.findDeclaration(diDecorators, 'Injectable'), Injectable);
this._registerDecoratorOrConstructor(this.findDeclaration(diDecorators, 'Self'), Self);
See code
This behaviour make is almost impossible to customise angular, you can customise in JIT but not in AOT.
Since the compiler can not get instructions how to resolve symbols for dynamic objects the experience between JIT and AOT is different.
Expected behavior
Allow developers to provide instruction to the compiler.
The best approach would be to use design-time decorators, not yet supported microsoft/TypeScript#2900
This gives the user the ability to provide design time information to the AOT compiler.
Until it lands a workaround to remove it can be using a webpack loader either via Transformers API or through a simple loader that removes that code in 2 places.
A great use case is mixins. Now that microsoft/TypeScript#13604 is in master, and will be in 2.2 this is really important for implementing the mixin pattern.
class User_ {
}
export const User = RestMixin(User);
export type User = User_ & Mixin
Currently, this will fail if User
is included as a provider.
There is no actual reason for it to fail since RestMixin
returns all the type information.
It fails because the compiler can't resolve User
into a symbol since it is dealing with complex function (RestMixin)
If I could notify the compiler what to do no compilation error.
In this case telling the compiler to resolve the symbol of User_
to User
In the current code I tried it via this hack, it worked:
if (staticSymbol.name === 'RestMixin') converter = (ctx, args) => { return args[0]};