diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/util.ts b/packages/compiler-cli/src/ngtsc/annotations/src/util.ts index 002a5803d7..a10ff41b54 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/util.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/util.ts @@ -49,22 +49,23 @@ export function getConstructorDependencies( let optional = false, self = false, skipSelf = false, host = false; let resolved = R3ResolvedDependencyType.Token; (param.decorators || []).filter(dec => isCore || isAngularCore(dec)).forEach(dec => { - if (dec.name === 'Inject') { + const name = isCore || dec.import === null ? dec.name : dec.import !.name; + if (name === 'Inject') { if (dec.args === null || dec.args.length !== 1) { throw new FatalDiagnosticError( ErrorCode.DECORATOR_ARITY_WRONG, dec.node, `Unexpected number of arguments to @Inject().`); } tokenExpr = dec.args[0]; - } else if (dec.name === 'Optional') { + } else if (name === 'Optional') { optional = true; - } else if (dec.name === 'SkipSelf') { + } else if (name === 'SkipSelf') { skipSelf = true; - } else if (dec.name === 'Self') { + } else if (name === 'Self') { self = true; - } else if (dec.name === 'Host') { + } else if (name === 'Host') { host = true; - } else if (dec.name === 'Attribute') { + } else if (name === 'Attribute') { if (dec.args === null || dec.args.length !== 1) { throw new FatalDiagnosticError( ErrorCode.DECORATOR_ARITY_WRONG, dec.node, @@ -74,8 +75,7 @@ export function getConstructorDependencies( resolved = R3ResolvedDependencyType.Attribute; } else { throw new FatalDiagnosticError( - ErrorCode.DECORATOR_UNEXPECTED, dec.node, - `Unexpected decorator ${dec.name} on parameter.`); + ErrorCode.DECORATOR_UNEXPECTED, dec.node, `Unexpected decorator ${name} on parameter.`); } }); if (tokenExpr === null) { diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 9c2c20c57e..1e50aab87d 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -160,6 +160,24 @@ describe('ngtsc behavioral tests', () => { expect(dtsContents).toContain('static ngInjectableDef: i0.ɵInjectableDef;'); }); + it('should compile @Injectable with an @Optional dependency', () => { + env.tsconfig(); + env.write('test.ts', ` + import {Injectable, Optional as Opt} from '@angular/core'; + + @Injectable() + class Dep {} + + @Injectable() + class Service { + constructor(@Opt() dep: Dep) {} + } + `); + env.driveMain(); + const jsContents = env.getContents('test.js'); + expect(jsContents).toContain('inject(Dep, 8)'); + }); + it('should compile Components (inline template) without errors', () => { env.tsconfig(); env.write('test.ts', `