diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts b/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts index 5f8c5d9bc9..c58b857603 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts @@ -45,8 +45,15 @@ export function generateSetClassMetadataCall( let metaCtorParameters: ts.Expression = ts.createNull(); const classCtorParameters = reflection.getConstructorParameters(clazz); if (classCtorParameters !== null) { - metaCtorParameters = ts.createArrayLiteral( + const ctorParameters = ts.createArrayLiteral( classCtorParameters.map(param => ctorParameterToMetadata(param, isCore))); + metaCtorParameters = ts.createFunctionExpression( + /* modifiers */ undefined, + /* asteriskToken */ undefined, + /* name */ undefined, + /* typeParameters */ undefined, + /* parameters */ undefined, + /* type */ undefined, ts.createBlock([ts.createReturn(ctorParameters)])); } // Do the same for property decorators. diff --git a/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts index 67ae1ac3a2..405e6ef6aa 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts @@ -35,7 +35,7 @@ describe('ngtsc setClassMetadata converter', () => { `/*@__PURE__*/ i0.ɵsetClassMetadata(Target, [{ type: Component, args: ['metadata'] }], null, null);`); }); - it('should convert decorated class construtor parameter metadata', () => { + it('should convert decorated class constructor parameter metadata', () => { const res = compileAndPrint(` import {Component, Inject, Injector} from '@angular/core'; const FOO = 'foo'; @@ -45,7 +45,7 @@ describe('ngtsc setClassMetadata converter', () => { } `); expect(res).toContain( - `[{ type: undefined, decorators: [{ type: Inject, args: [FOO] }] }, { type: Injector }], null);`); + `function () { return [{ type: undefined, decorators: [{ type: Inject, args: [FOO] }] }, { type: Injector }]; }, null);`); }); it('should convert decorated field metadata', () => { diff --git a/packages/core/src/render3/metadata.ts b/packages/core/src/render3/metadata.ts index bb5b4be0ee..19988e1d2f 100644 --- a/packages/core/src/render3/metadata.ts +++ b/packages/core/src/render3/metadata.ts @@ -10,7 +10,7 @@ import {Type} from '../type'; interface TypeWithMetadata extends Type { decorators?: any[]; - ctorParameters?: any[]; + ctorParameters?: () => any[]; propDecorators?: {[field: string]: any}; } @@ -24,7 +24,7 @@ interface TypeWithMetadata extends Type { * tree-shaken away during production builds. */ export function setClassMetadata( - type: Type, decorators: any[] | null, ctorParameters: any[] | null, + type: Type, decorators: any[] | null, ctorParameters: (() => any[]) | null, propDecorators: {[field: string]: any} | null): void { const clazz = type as TypeWithMetadata; if (decorators !== null) { diff --git a/packages/core/test/render3/metadata_spec.ts b/packages/core/test/render3/metadata_spec.ts index 89d7f45ff4..26494a6e37 100644 --- a/packages/core/test/render3/metadata_spec.ts +++ b/packages/core/test/render3/metadata_spec.ts @@ -16,7 +16,7 @@ interface Decorator { interface HasMetadata extends Type { decorators?: Decorator[]; - ctorParameters: {type: any, decorators?: Decorator[]}[]; + ctorParameters: () => CtorParameter[]; propDecorators: {[field: string]: Decorator[]}; } @@ -45,9 +45,9 @@ describe('render3 setClassMetadata()', () => { it('should set ctor parameter metadata on a type', () => { const Foo = metadataOf(class Foo{}); - Foo.ctorParameters = [{type: 'initial'}]; - setClassMetadata(Foo, null, [{type: 'test'}], null); - expect(Foo.ctorParameters).toEqual([{type: 'test'}]); + Foo.ctorParameters = () => [{type: 'initial'}]; + setClassMetadata(Foo, null, () => [{type: 'test'}], null); + expect(Foo.ctorParameters()).toEqual([{type: 'test'}]); }); it('should set parameter decorator metadata on a type', () => {