diff --git a/packages/ngtools/webpack/src/transformers/elide_imports.ts b/packages/ngtools/webpack/src/transformers/elide_imports.ts index 21303f45b847..9107926876c9 100644 --- a/packages/ngtools/webpack/src/transformers/elide_imports.ts +++ b/packages/ngtools/webpack/src/transformers/elide_imports.ts @@ -39,6 +39,13 @@ export function elideImports( return; } + // Consider types for 'implements' as unused. + // A HeritageClause token can also be an 'AbstractKeyword' + // which in that case we should not elide the import. + if (ts.isHeritageClause(node) && node.token === ts.SyntaxKind.ImplementsKeyword) { + return; + } + // Record import and skip if (ts.isImportDeclaration(node)) { imports.push(node); diff --git a/packages/ngtools/webpack/src/transformers/elide_imports_spec.ts b/packages/ngtools/webpack/src/transformers/elide_imports_spec.ts index 2311cadc7a48..d037e77d3f6e 100644 --- a/packages/ngtools/webpack/src/transformers/elide_imports_spec.ts +++ b/packages/ngtools/webpack/src/transformers/elide_imports_spec.ts @@ -317,6 +317,27 @@ describe('@ngtools/webpack transformers', () => { }); }); + it(`should remove import for 'ExpressionWithTypeArguments' implements token`, () => { + const input = tags.stripIndent` + import { Bar, Buz, Unused } from './bar'; + + export class Foo extends Bar implements Buz { } + + ${dummyNode} + `; + + const output = tags.stripIndent` + import { Bar } from './bar'; + + export class Foo extends Bar { } + `; + + const { program, compilerHost } = createTypescriptContext(input); + const result = transformTypescript(undefined, [transformer(program)], program, compilerHost); + + expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`); + }); + describe('should not elide imports decorator type references when emitDecoratorMetadata is true', () => { const extraCompilerOptions: ts.CompilerOptions = { emitDecoratorMetadata: true,