-
Notifications
You must be signed in to change notification settings - Fork 25.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AoT error with @Inject
and interface type
#12631
Comments
/cc @chuckjaz |
I am also experiencing this with
Further details in #12860. |
Same here by using in my constructor. I confirm the @jeffbcross error and agree we shouldn't have to type using |
Getting the same thing export interface LazyMapsAPILoaderConfigLiteral {
/**
* The Google Maps API Key (see:
* https://developers.google.com/maps/documentation/javascript/get-api-key)
*/
apiKey?: string;
/**
* The Google Maps client ID (for premium plans).
* When you have a Google Maps APIs Premium Plan license, you must authenticate
* your application with either an API key or a client ID.
* The Google Maps API will fail to load if both a client ID and an API key are included.
*/
clientId?: string;
}
@Injectable()
export class LazyMapsAPILoader extends MapsAPILoader {
private _scriptLoadingPromise: Promise<void>;
constructor(
@Inject(LAZY_MAPS_API_CONFIG) private _config: LazyMapsAPILoaderConfigLiteral,
) {
super();
this._config = this._config || {};
}
//...
} Fails with
|
Getting the same thing with a test component (AOT really miss a feature to exclude things):
The component is only used for testing but still AOT insist it should be defined in a module (otherwise another error will occur) and when processing AOT produces this error:
A complete blocker - could not be more serious. Only way forward is to delete all my advanced tests in order to get AOT working... NO |
but u can just change type to any... or change interface to abstract class |
Thanks. This workaround works too. Annoying that I lose type safety here but at least I can proceed. |
I believe u can do something like
|
Yes indeed. I actually did exactly what you suggest with an additional comment referencing this bug to explain why I had to write bad code like this (it hurts to write 'any', to do type conversions and to add seemingly unnecessary lines of code ;-)) |
Wow this took a long time to find on Google. This is still happening in 2.4.1 using @ngtools/webpack npm package. Why does AOT even care about constructor arguments? |
In this case it shouldn't. In general, if no |
Provider Alias also depend of |
I am having this as well. This fails with AoT compiler in Angular CLI, because
With error:
(More details in #14050) The workaround (other than using
|
Still happening on v2.4.4. Trying to inject angular's import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
@Injectable()
export class MyService {
constructor(
@Inject(DOCUMENT) doc: Document // <-- This fails with ngc =(
) { }
} |
I'm also facing this attempting to inject Window. This is a major pain for real-world apps. |
Our team is facing the same issue. Rather than solving it by (temporarily) changing the type for such parameters to export interface MyConfig {
foo: string;
bar: boolean;
baz(a: number): Date;
}
abstract class MyConfigClass implements MyConfig {
foo: string;
bar: boolean;
baz(a: number): Date;
}
@Injectable()
export class MyService {
// Use MyConfigClass here instead of the MyConfig interface
constructor(@Inject(MY_CONFIG_TOKEN) config: MyConfigClass) {
}
} This ain't pretty and has the drawback of having to repeat the interface definition again in the (abstract) class, but at least it is type safe. |
@dscheerens see my version of this in this #12631 (comment). In TypeScript, a |
@Meligy I actually tried that, but that only seems to work for the Window interface. If I do this for my own interface, TypeScript is complaining that you cannot extend an interface:
I also tried to mimic the same behavior from the Window interface by doing this: declare var MyConfig: {
prototype: MyConfig;
new(): MyConfig;
} That works to get rid of the cannot extend an interface message, but then NGC again gives me an error that it cannot resolve |
I went for some help from Twitter to find out why. Here's how to do it: interface RealInterface {
title: string;
}
// This does the trick, a `var`, with `new` and `prototype`
declare var RealInterface: {
prototype: RealInterface;
new(): RealInterface;
};
class FakeClass extends RealInterface {
} Thanks @dscheerens. I just learned something new :) |
@Meligy That works to for the extend stuff, but you'll end up with the initial AoT compilation error. So unfortunately it doesn't help as a workaround for the AoT issues. |
It was nice if typescript would export something for interfaces the angular DI could work with. But until then you can use abstract instead of interface: https://plnkr.co/edit/xzGHB54LVOb2If6mJfZl?p=preview abstract class AbstractFooService {
abstract fooProperty: string;
}
class FooService implements AbstractFooService {
fooProperty = 'string from service'
}
@Component({
providers: [{provide: AbstractFooService, useClass: FooService}],
selector: 'my-app',
template: `{{ fooService.fooProperty }}`
})
export class AppComponent {
constructor(public fooService: AbstractFooService) {
}
} The angular team does the same right now - e.g. the ReflectorReader provided by that abstract token. If everything is abstract in the abstract class, all that is left is an empty function after transpilation to es5. |
Thanks @DzmitryShylovich for referencing my issue here. |
@skdhir for example:
|
@DzmitryShylovich Yep. I mean I'm having this issue for Ionic 2 - having function in app.module.ts:
which in httpInterceptor.ts :
Now the ngc is saying me: |
@matejamateusz remove And don't extend |
@DzmitryShylovich What do you mean by wrapper? |
@chuckjaz Is this fixed in v4 ? If so, I have a good reason for upgrading :-) |
not yet |
@DzmitryShylovich Thanks for the info. It seems whenever I have a angular question/issue, you provide a good answer within 5 minutes. Very impressive. I can't state enough how much your help is appreciated! |
Exactly the same feeling!;)
…On Sat, 11 Mar 2017 at 13:50, Morten Christensen ***@***.***> wrote:
@DzmitryShylovich <https://github.com/DzmitryShylovich> Thanks for the
info. It seems whenever I have a angular question/issue, you provide a good
answer within 5 minutes. Very impressive. I can't state enough how much
your help is appreciated!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#12631 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AGIbY-_Ct977IKZ1LjSQnOF5c4t1CeDuks5rkpingaJpZM4KlXt9>
.
|
#14894 the fix |
Are you sure this works with ng build --prod? |
@MadUser it does work using plain ngc. If it doesn't work in cli then it's a cli issue |
Works fine for me with angular cli 1.0 and angular 4.0 project |
Due to a bug (angular/angular#12631 (comment)), specifiying a type for a injected provider didn't work in AOT mode. This bug has been solved, but we still need to switch to a `interface` instead of a TypeScript `type`.
Due to a bug (angular/angular#12631 (comment)), specifiying a type for a injected provider didn't work in AOT mode. This bug has been solved, but we still need to switch to a `interface` instead of a TypeScript `type`.
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
I'm submitting a ... (check one with "x")
Current behavior
I have a constructor that uses
@Inject
to get a dependency, and references an interface for that the dep,constructor( @Inject(FirebaseApp) _fbApp: firebase.app.App)
. When I compile the lib withngc
, I get this error:If I change the type to
any
, compilation succeeds.Expected behavior
I would expect to be able to reference an interface in a constructor in conjunction with
@Inject
.Minimal reproduction of the problem with instructions
ngc
this thing:@angular/[email protected]
@angular/[email protected]
node --version
=Node 5.10.1
The text was updated successfully, but these errors were encountered: