diff --git a/packages/jsii/lib/transforms/deprecated-remover.ts b/packages/jsii/lib/transforms/deprecated-remover.ts index b3f14649ef..82bf54f36a 100644 --- a/packages/jsii/lib/transforms/deprecated-remover.ts +++ b/packages/jsii/lib/transforms/deprecated-remover.ts @@ -591,7 +591,11 @@ class Transformation { const symbol = typeChecker.getSymbolAtLocation( ts.getNameOfDeclaration(node as ts.Declaration) ?? node, ); - return symbol && typeChecker.getFullyQualifiedName(symbol); + // This symbol ☝️ does not contain enough information in some cases - when + // an imported type is part of a heritage clause - to produce the fqn. + // Round tripping this to its type and back to a symbol seems to fix this. + const type = symbol && typeChecker.getDeclaredTypeOfSymbol(symbol); + return type?.symbol && typeChecker.getFullyQualifiedName(type.symbol); } private static typeReference( diff --git a/packages/jsii/test/deprecated-remover.test.ts b/packages/jsii/test/deprecated-remover.test.ts index 109509daf2..3ba3990175 100644 --- a/packages/jsii/test/deprecated-remover.test.ts +++ b/packages/jsii/test/deprecated-remover.test.ts @@ -1,4 +1,4 @@ -import { compileJsiiForTest } from '../lib'; +import { compileJsiiForTest, HelperCompilationResult } from '../lib'; const DEPRECATED = '/** @deprecated stripped */'; @@ -114,15 +114,7 @@ test('produces correct output', async () => { }, } `); - expect( - Object.entries(result.files) - .filter(([name]) => name.endsWith('.d.ts')) - .map(([name, content]) => { - const separator = '/'.repeat(name.length + 8); - return `${separator}\n/// ${name} ///\n${content}${separator}\n`; - }) - .join('\n\n'), - ).toMatchInlineSnapshot(` + expect(declFilesSnapshot(result)).toMatchInlineSnapshot(` "////////////////// /// index.d.ts /// import './deprecated'; @@ -159,3 +151,47 @@ test('produces correct output', async () => { " `); }); + +test('cross-file deprecated heritage', async () => { + const result = await compileJsiiForTest( + { + 'index.ts': ` + import { IDeprecated } from './deprecated'; + export * from './deprecated'; + export interface INotDeprecated extends IDeprecated {} + `, + 'deprecated.ts': ` + ${DEPRECATED} + export interface IDeprecated {} + `, + }, + undefined /* callback */, + { stripDeprecated: true }, + ); + + expect(declFilesSnapshot(result)).toMatchInlineSnapshot(` + "////////////////// + /// index.d.ts /// + import './deprecated'; + import './deprecated'; + export interface INotDeprecated { + } + ////////////////// + + + /////////////////////// + /// deprecated.d.ts /// + /////////////////////// + " + `); +}); + +function declFilesSnapshot(result: HelperCompilationResult) { + return Object.entries(result.files) + .filter(([name]) => name.endsWith('.d.ts')) + .map(([name, content]) => { + const separator = '/'.repeat(name.length + 8); + return `${separator}\n/// ${name} ///\n${content}${separator}\n`; + }) + .join('\n\n'); +}