diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a53c1841b6ef4..e3d5b4b5c5c18 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25740,9 +25740,7 @@ namespace ts { return getTypeOfSymbol(symbol); } - // We should only mark aliases as referenced if there isn't a local value declaration - // for the symbol. Also, don't mark any property access expression LHS - checkPropertyAccessExpression will handle that - if (!(node.parent && isPropertyAccessExpression(node.parent) && node.parent.expression === node)) { + if (shouldMarkIdentifierAliasReferenced(node)) { markAliasReferenced(symbol, node); } @@ -25890,6 +25888,25 @@ namespace ts { return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; } + function shouldMarkIdentifierAliasReferenced(node: Identifier): boolean { + const parent = node.parent; + if (parent) { + // A property access expression LHS? checkPropertyAccessExpression will handle that. + if (isPropertyAccessExpression(parent) && parent.expression === node) { + return false; + } + // Next two check for an identifier inside a type only export. + if (isExportSpecifier(parent) && parent.isTypeOnly) { + return false; + } + const greatGrandparent = parent.parent?.parent; + if (greatGrandparent && isExportDeclaration(greatGrandparent) && greatGrandparent.isTypeOnly) { + return false; + } + } + return true; + } + function isInsideFunctionOrInstancePropertyInitializer(node: Node, threshold: Node): boolean { return !!findAncestor(node, n => n === threshold ? "quit" : isFunctionLike(n) || ( n.parent && isPropertyDeclaration(n.parent) && !hasStaticModifier(n.parent) && n.parent.initializer === n @@ -41225,7 +41242,9 @@ namespace ts { error(exportedName, Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, idText(exportedName)); } else { - markExportAsReferenced(node); + if (!node.isTypeOnly && !node.parent.parent.isTypeOnly) { + markExportAsReferenced(node); + } const target = symbol && (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol); if (!target || target === unknownSymbol || target.flags & SymbolFlags.Value) { checkExpressionCached(node.propertyName || node.name); diff --git a/src/testRunner/unittests/services/transpile.ts b/src/testRunner/unittests/services/transpile.ts index 2e0c8ea24547a..e0cfa72f53eb5 100644 --- a/src/testRunner/unittests/services/transpile.ts +++ b/src/testRunner/unittests/services/transpile.ts @@ -485,5 +485,19 @@ export { a as alias }; export * as alias from './file';`, { noSetFileName: true }); + + transpilesCorrectly("Elides import equals referenced only by export type", + `import IFoo = Namespace.IFoo;` + + `export type { IFoo };`, { + options: { compilerOptions: { module: ModuleKind.CommonJS } } + } + ); + + transpilesCorrectly("Elides import equals referenced only by type only export specifier", + `import IFoo = Namespace.IFoo;` + + `export { type IFoo };`, { + options: { compilerOptions: { module: ModuleKind.CommonJS } } + } + ); }); } diff --git a/tests/baselines/reference/transpile/Elides import equals referenced only by export type.js b/tests/baselines/reference/transpile/Elides import equals referenced only by export type.js new file mode 100644 index 0000000000000..e9493d9d5917d --- /dev/null +++ b/tests/baselines/reference/transpile/Elides import equals referenced only by export type.js @@ -0,0 +1,3 @@ +"use strict"; +exports.__esModule = true; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Elides import equals referenced only by export type.oldTranspile.js b/tests/baselines/reference/transpile/Elides import equals referenced only by export type.oldTranspile.js new file mode 100644 index 0000000000000..e9493d9d5917d --- /dev/null +++ b/tests/baselines/reference/transpile/Elides import equals referenced only by export type.oldTranspile.js @@ -0,0 +1,3 @@ +"use strict"; +exports.__esModule = true; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Elides import equals referenced only by type only export specifier.js b/tests/baselines/reference/transpile/Elides import equals referenced only by type only export specifier.js new file mode 100644 index 0000000000000..e9493d9d5917d --- /dev/null +++ b/tests/baselines/reference/transpile/Elides import equals referenced only by type only export specifier.js @@ -0,0 +1,3 @@ +"use strict"; +exports.__esModule = true; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Elides import equals referenced only by type only export specifier.oldTranspile.js b/tests/baselines/reference/transpile/Elides import equals referenced only by type only export specifier.oldTranspile.js new file mode 100644 index 0000000000000..e9493d9d5917d --- /dev/null +++ b/tests/baselines/reference/transpile/Elides import equals referenced only by type only export specifier.oldTranspile.js @@ -0,0 +1,3 @@ +"use strict"; +exports.__esModule = true; +//# sourceMappingURL=file.js.map \ No newline at end of file