Skip to content

Commit

Permalink
fix(compiler): type-only symbols incorrectly retained when downlevell…
Browse files Browse the repository at this point in the history
…ing custom decorators (#48638)

In #47167 an `updateClassDeclaration` call was swapped out with a `createClassDeclaration` which caused a regression where interface references were being retained when using a custom decorator in a project that has `emitDecoratorMetadata` enabled.

These changes switch back to use `updateClassDeclaration`.

Fixes #48448.

PR Close #48638
  • Loading branch information
crisbeto authored and alxhub committed Jan 4, 2023
1 parent 2d3c98d commit 33f35b0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -576,8 +576,9 @@ export function getDownlevelDecoratorsTransform(
modifiers = [...decoratorsToKeep, ...(classModifiers || [])];
}

return ts.factory.createClassDeclaration(
modifiers, classDecl.name, classDecl.typeParameters, classDecl.heritageClauses, members);
return ts.factory.updateClassDeclaration(
classDecl, modifiers, classDecl.name, classDecl.typeParameters, classDecl.heritageClauses,
members);
}

/**
Expand Down
27 changes: 27 additions & 0 deletions packages/compiler-cli/test/downlevel_decorators_transform_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,33 @@ describe('downlevel decorator transform', () => {
expect(output).not.toContain('tslib');
});

it('should allow for type-only references to be removed with `emitDecoratorMetadata` from custom decorators',
() => {
context.writeFile('/external-interface.ts', `
export interface ExternalInterface {
id?: string;
}
`);

const {output} = transform(
`
import { ExternalInterface } from './external-interface';
export function CustomDecorator() {
return <T>(target, propertyKey, descriptor: TypedPropertyDescriptor<T>) => {}
}
export class Foo {
@CustomDecorator() static test(): ExternalInterface { return {}; }
}
`,
{emitDecoratorMetadata: true});

expect(diagnostics.length).toBe(0);
expect(output).not.toContain('ExternalInterface');
expect(output).toContain('metadata("design:returntype", Object)');
});

describe('class decorators skipped', () => {
beforeEach(() => skipClassDecorators = true);

Expand Down

0 comments on commit 33f35b0

Please sign in to comment.