diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bf6e578c1ca..39a3f79694c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34018,7 +34018,7 @@ namespace ts { return false; } if (inAmbientExternalModule && isExternalModuleNameRelative(moduleName.text)) { - // we have already reported errors on top level imports\exports in external module augmentations in checkModuleDeclaration + // we have already reported errors on top level imports/exports in external module augmentations in checkModuleDeclaration // no need to do this again. if (!isTopLevelInExternalModuleAugmentation(node)) { // TypeScript 1.0 spec (April 2013): 12.1.6 @@ -34154,16 +34154,10 @@ namespace ts { checkGrammarExportDeclaration(node); if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { - if (node.exportClause) { + if (node.exportClause && !isNamespaceExport(node.exportClause)) { // export { x, y } // export { x, y } from "foo" - if (isNamedExports(node.exportClause)) { - forEach(node.exportClause.elements, checkExportSpecifier); - } - else if(!isNamespaceExport(node.exportClause)) { - checkImportBinding(node.exportClause); - } - + forEach(node.exportClause.elements, checkExportSpecifier); const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent); const inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === SyntaxKind.ModuleBlock && !node.moduleSpecifier && node.flags & NodeFlags.Ambient; @@ -34177,7 +34171,9 @@ namespace ts { if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) { error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol)); } - + else if (node.exportClause) { + checkAliasSymbol(node.exportClause); + } if (moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015) { checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar); } diff --git a/tests/baselines/reference/exportAsNamespace_exportAssignment.errors.txt b/tests/baselines/reference/exportAsNamespace_exportAssignment.errors.txt new file mode 100644 index 00000000000..07e1001d87a --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_exportAssignment.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/es2020/modules/b.ts(1,21): error TS2498: Module '"tests/cases/conformance/es2020/modules/a"' uses 'export =' and cannot be used with 'export *'. + + +==== tests/cases/conformance/es2020/modules/a.ts (0 errors) ==== + export = {} + +==== tests/cases/conformance/es2020/modules/b.ts (1 errors) ==== + export * as ns from './a'; + ~~~~~ +!!! error TS2498: Module '"tests/cases/conformance/es2020/modules/a"' uses 'export =' and cannot be used with 'export *'. + \ No newline at end of file diff --git a/tests/baselines/reference/exportAsNamespace_exportAssignment.js b/tests/baselines/reference/exportAsNamespace_exportAssignment.js new file mode 100644 index 00000000000..36e08b627da --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_exportAssignment.js @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/es2020/modules/exportAsNamespace_exportAssignment.ts] //// + +//// [a.ts] +export = {} + +//// [b.ts] +export * as ns from './a'; + + +//// [a.js] +"use strict"; +module.exports = {}; +//// [b.js] +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +exports.__esModule = true; +exports.ns = __importStar(require("./a")); diff --git a/tests/baselines/reference/exportAsNamespace_missingEmitHelpers.errors.txt b/tests/baselines/reference/exportAsNamespace_missingEmitHelpers.errors.txt new file mode 100644 index 00000000000..d50cf7a1754 --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_missingEmitHelpers.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/es2020/modules/b.ts(1,1): error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. + + +==== tests/cases/conformance/es2020/modules/a.ts (0 errors) ==== + export {} + +==== tests/cases/conformance/es2020/modules/b.ts (1 errors) ==== + export * as ns from './a'; // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. + \ No newline at end of file diff --git a/tests/baselines/reference/exportAsNamespace_missingEmitHelpers.js b/tests/baselines/reference/exportAsNamespace_missingEmitHelpers.js new file mode 100644 index 00000000000..e7691f4d439 --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_missingEmitHelpers.js @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/es2020/modules/exportAsNamespace_missingEmitHelpers.ts] //// + +//// [a.ts] +export {} + +//// [b.ts] +export * as ns from './a'; // Error + + +//// [a.js] +"use strict"; +exports.__esModule = true; +//// [b.js] +"use strict"; +exports.__esModule = true; +exports.ns = require("./a"); // Error diff --git a/tests/baselines/reference/exportAsNamespace_nonExistent.errors.txt b/tests/baselines/reference/exportAsNamespace_nonExistent.errors.txt new file mode 100644 index 00000000000..c8985bee196 --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_nonExistent.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/es2020/modules/exportAsNamespace_nonExistent.ts(1,21): error TS2307: Cannot find module './nonexistent' or its corresponding type declarations. + + +==== tests/cases/conformance/es2020/modules/exportAsNamespace_nonExistent.ts (1 errors) ==== + export * as ns from './nonexistent'; // Error + ~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './nonexistent' or its corresponding type declarations. + \ No newline at end of file diff --git a/tests/baselines/reference/exportAsNamespace_nonExistent.js b/tests/baselines/reference/exportAsNamespace_nonExistent.js new file mode 100644 index 00000000000..bd915fd090e --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_nonExistent.js @@ -0,0 +1,6 @@ +//// [exportAsNamespace_nonExistent.ts] +export * as ns from './nonexistent'; // Error + + +//// [exportAsNamespace_nonExistent.js] +export * as ns from './nonexistent'; // Error diff --git a/tests/cases/conformance/es2020/modules/exportAsNamespace_exportAssignment.ts b/tests/cases/conformance/es2020/modules/exportAsNamespace_exportAssignment.ts new file mode 100644 index 00000000000..9b8f83b284e --- /dev/null +++ b/tests/cases/conformance/es2020/modules/exportAsNamespace_exportAssignment.ts @@ -0,0 +1,9 @@ +// @module: commonjs +// @esModuleInterop: true +// @noTypesAndSymbols: true + +// @Filename: a.ts +export = {} + +// @Filename: b.ts +export * as ns from './a'; diff --git a/tests/cases/conformance/es2020/modules/exportAsNamespace_missingEmitHelpers.ts b/tests/cases/conformance/es2020/modules/exportAsNamespace_missingEmitHelpers.ts new file mode 100644 index 00000000000..5ace102ce56 --- /dev/null +++ b/tests/cases/conformance/es2020/modules/exportAsNamespace_missingEmitHelpers.ts @@ -0,0 +1,9 @@ +// @module: commonjs +// @importHelpers: true +// @noTypesAndSymbols: true + +// @Filename: a.ts +export {} + +// @Filename: b.ts +export * as ns from './a'; // Error diff --git a/tests/cases/conformance/es2020/modules/exportAsNamespace_nonExistent.ts b/tests/cases/conformance/es2020/modules/exportAsNamespace_nonExistent.ts new file mode 100644 index 00000000000..ccb95bb9c63 --- /dev/null +++ b/tests/cases/conformance/es2020/modules/exportAsNamespace_nonExistent.ts @@ -0,0 +1,4 @@ +// @module: esnext +// @noTypesAndSymbols: true + +export * as ns from './nonexistent'; // Error