diff --git a/packages/compiler/src/aot/static_reflector.ts b/packages/compiler/src/aot/static_reflector.ts index cf6f796635..fbd0ed5292 100644 --- a/packages/compiler/src/aot/static_reflector.ts +++ b/packages/compiler/src/aot/static_reflector.ts @@ -182,16 +182,16 @@ export class StaticReflector implements CompileReflector { const ctorData = members ? members['__ctor__'] : null; if (ctorData) { const ctor = (ctorData).find(a => a['__symbolic'] == 'constructor'); - const parameterTypes = this.simplify(type, ctor['parameters'] || []); + const rawParameterTypes = ctor['parameters'] || []; const parameterDecorators = this.simplify(type, ctor['parameterDecorators'] || []); parameters = []; - parameterTypes.forEach((paramType, index) => { + rawParameterTypes.forEach((rawParamType, index) => { const nestedResult: any[] = []; - if (paramType) { - nestedResult.push(paramType); - } + const paramType = this.trySimplify(type, rawParamType); + if (paramType) nestedResult.push(paramType); const decorators = parameterDecorators ? parameterDecorators[index] : null; if (decorators) { + if (paramType) nestedResult.push(paramType); nestedResult.push(...decorators); } parameters !.push(nestedResult); diff --git a/packages/compiler/test/aot/static_reflector_spec.ts b/packages/compiler/test/aot/static_reflector_spec.ts index 9ea0ffda15..4b77018fb1 100644 --- a/packages/compiler/test/aot/static_reflector_spec.ts +++ b/packages/compiler/test/aot/static_reflector_spec.ts @@ -570,6 +570,48 @@ describe('StaticReflector', () => { expect(annotation.providers).toEqual([]); }); + // #15424 + it('should be able to inject a ctor parameter with a @Inject and a type expression', () => { + const data = Object.create(DEFAULT_TEST_DATA); + const file = '/tmp/src/invalid-component.ts'; + data[file] = ` + import {Injectable, Inject} from '@angular/core'; + + @Injectable() + export class SomeClass { + constructor (@Inject('some-token') a: {a: string, b: string}) {} + } + `; + init(data); + + const someClass = reflector.getStaticSymbol(file, 'SomeClass'); + const parameters = reflector.parameters(someClass); + expect(parameters.toString()).toEqual('@Inject'); + }); + + it('should reject a ctor parameter without a @Inject and a type exprssion', () => { + const data = Object.create(DEFAULT_TEST_DATA); + const file = '/tmp/src/invalid-component.ts'; + data[file] = ` + import {Injectable} from '@angular/core'; + + @Injectable() + export class SomeClass { + constructor (a: {a: string, b: string}) {} + } + `; + + let error: any = undefined; + init(data, [], (err: any, filePath: string) => { + expect(error).toBeUndefined(); + error = err; + }); + + const someClass = reflector.getStaticSymbol(file, 'SomeClass'); + expect(reflector.parameters(someClass)).toEqual([[]]); + expect(error).toBeUndefined(); + }); + describe('inheritance', () => { class ClassDecorator { constructor(public value: any) {}