Skip to content

Commit 3e444fb

Browse files
alan-agius4dgp1130
authored andcommitted
fix(@ngtools/webpack): handle union type with a nullable argument
Currently constructor parameters with union types that contains nullable argument are not being converted properly and result in broken behaviour. With this change we align the ctor-parameters downlevel transformer to be closer to the NGTSC reflector: https://github.com/angular/angular/blob/master/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts#L65-L66 This change should also be synced to ng-packagr. Closes: #17063 Reference: FW-1883 (cherry picked from commit 826803d)
1 parent b277030 commit 3e444fb

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

packages/ngtools/webpack/src/transformers/ctor-parameters.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,13 @@ function typeReferenceToExpression(
174174
case ts.SyntaxKind.NumberKeyword:
175175
case ts.SyntaxKind.NumericLiteral:
176176
return ts.createIdentifier('Number');
177+
case ts.SyntaxKind.UnionType:
178+
const childTypeNodes = (node as ts.UnionTypeNode).types.filter(t => t.kind !== ts.SyntaxKind.NullKeyword);
179+
180+
return childTypeNodes.length === 1
181+
? typeReferenceToExpression(entityNameToExpression, childTypeNodes[0], typeChecker)
182+
: undefined;
183+
177184
case ts.SyntaxKind.TypeReference:
178185
const typeRef = node as ts.TypeReferenceNode;
179186
let typeSymbol = typeChecker.getSymbolAtLocation(typeRef.typeName);

packages/ngtools/webpack/src/transformers/ctor-parameters_spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function transform(input: string, additionalFiles?: Record<string, string>) {
1717
return result;
1818
}
1919

20+
// tslint:disable-next-line: no-big-function
2021
describe('Constructor Parameter Transformer', () => {
2122
it('records class name in same module', () => {
2223
const input = `
@@ -211,4 +212,40 @@ describe('Constructor Parameter Transformer', () => {
211212

212213
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
213214
});
215+
216+
it('should work with union type and nullable argument', () => {
217+
const input = `
218+
@Injectable()
219+
export class ProvidedService {
220+
constructor() { }
221+
}
222+
223+
@Injectable()
224+
export class LibService {
225+
constructor(
226+
@Optional() private service: ProvidedService | null,
227+
) {
228+
}
229+
}
230+
`;
231+
232+
const output = `
233+
import { __decorate, __param } from "tslib";
234+
235+
let ProvidedService = class ProvidedService { constructor() { } };
236+
ProvidedService = __decorate([ Injectable() ], ProvidedService);
237+
export { ProvidedService };
238+
239+
let LibService = class LibService {
240+
constructor(service) { this.service = service; }
241+
};
242+
LibService.ctorParameters = () => [ { type: ProvidedService, decorators: [{ type: Optional }] } ];
243+
LibService = __decorate([ Injectable(), __param(0, Optional()) ], LibService);
244+
export { LibService };
245+
`;
246+
247+
const result = transform(input);
248+
249+
expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
250+
});
214251
});

0 commit comments

Comments
 (0)