我有以下构造函数:
constructor(env: Env, private logger: Logger,
@Inject(MockEndpoints.TOKEN) @Optional()
private endpoints: MockEndpoints[]) {
// ...
}
与JIT编译器一样正常工作。
但是启用AOT编译器会产生构建错误:
ERROR in : Can't resolve all parameters for MockBackendInterceptor in /path/mock-backend.interceptor.ts: ([object Object], [object Object], ?).
令牌对象定义如下:
export interface MockEndpoints {
handle(req: HttpRequest<any>): HttpResponse<any>;
}
export namespace MockEndpoints {
export const TOKEN: InjectionToken<MockEndpoints[]> =
new InjectionToken<MockEndpoints[]>('MockEndpoints');
}
我确信这完全符合文档的建议。 任何提示? ;)
编辑(作为对Gunter评论的回应): 端点在同一模块中注册:@NgModule({
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: MockBackendInterceptor, multi: true },
{ provide: MockEndpoints.TOKEN, useClass: MockBackupService, multi: true },
{ provide: MockEndpoints.TOKEN, useClass: MockConfigurationService, multi: true }
]
})
export class MockBackendModule { }
答案 0 :(得分:1)
最后我找到了原因。
非常感谢用户yurzui
和Günter Zöchbauer
提供了有助于发现问题的评论。
<强>解强>
如果(且仅当)在命名空间内声明令牌常量,
InjectionToken
的参数化类型(例如,在这种情况下为MockEndpoints
)不能是接口。因此,将其改为抽象类就足够了。
export abstract class MockEndpoints {
handle(req: HttpRequest<any>): HttpResponse<any>;
}
export namespace MockEndpoints {
export const TOKEN: InjectionToken<MockEndpoints[]> =
new InjectionToken<MockEndpoints[]>('MockEndpoints');
}
从命名空间中提取TOKEN常量甚至更简单。
export interface MockEndpoint {
handle(req: HttpRequest<any>): HttpResponse<any>;
}
export const MOCK_ENDPOINT = new InjectionToken<MockEndpoint[]>('MockEndpoints');
请注意,名称空间名称与接口名称相同(在本例中为两个名称MockEndpoints
)没有任何意义。当在名称空间不同的名称内声明令牌常量时,它不能作为参数化类型使用接口。
当然它也可以使用普通字符串标记,而不是使用InjectionToken
接口。
仅在使用AOT进行编译时才会发生此行为。有了JIT,两种情况都没有问题。