diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 133065b4e8..78ff1efc86 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1966,7 +1966,21 @@ namespace ts { const file = find(moduleSymbol.declarations, isSourceFile); const hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias); if (!exportDefaultSymbol && !hasSyntheticDefault) { - error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol)); + if (hasExportAssignmentSymbol(moduleSymbol)) { + const compilerOptionName = moduleKind >= ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; + const exportEqualsSymbol = moduleSymbol.exports!.get(InternalSymbolName.ExportEquals); + const exportAssignment = exportEqualsSymbol!.valueDeclaration; + const err = error(node.name, Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); + + addRelatedInfo(err, createDiagnosticForNode( + exportAssignment, + Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, + compilerOptionName + )); + } + else { + error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol)); + } } else if (hasSyntheticDefault) { // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index cd08731be0..0df9c2e4de 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -851,6 +851,10 @@ "category": "Error", "code": 1258 }, + "Module '{0}' can only be default-imported using the '{1}' flag": { + "category": "Error", + "code": 1259 + }, "'with' statements are not allowed in an async function block.": { "category": "Error", "code": 1300 @@ -2156,6 +2160,10 @@ "category": "Error", "code": 2593 }, + "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag.": { + "category": "Error", + "code": 2594 + }, "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", "code": 2600 diff --git a/tests/baselines/reference/allowSyntheticDefaultImports6.errors.txt b/tests/baselines/reference/allowSyntheticDefaultImports6.errors.txt index 80b9cf8d07..916f50162a 100644 --- a/tests/baselines/reference/allowSyntheticDefaultImports6.errors.txt +++ b/tests/baselines/reference/allowSyntheticDefaultImports6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/a.ts(1,8): error TS1192: Module '"tests/cases/compiler/b"' has no default export. +tests/cases/compiler/a.ts(1,8): error TS1259: Module '"tests/cases/compiler/b"' can only be default-imported using the 'esModuleInterop' flag ==== tests/cases/compiler/b.d.ts (0 errors) ==== @@ -10,6 +10,7 @@ tests/cases/compiler/a.ts(1,8): error TS1192: Module '"tests/cases/compiler/b"' ==== tests/cases/compiler/a.ts (1 errors) ==== import Foo from "./b"; ~~~ -!!! error TS1192: Module '"tests/cases/compiler/b"' has no default export. +!!! error TS1259: Module '"tests/cases/compiler/b"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/b.d.ts:4:1: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. export var x = new Foo(); \ No newline at end of file diff --git a/tests/baselines/reference/es6ExportEqualsInterop.errors.txt b/tests/baselines/reference/es6ExportEqualsInterop.errors.txt index 5b8e83b3cc..d7b992f2c1 100644 --- a/tests/baselines/reference/es6ExportEqualsInterop.errors.txt +++ b/tests/baselines/reference/es6ExportEqualsInterop.errors.txt @@ -1,16 +1,16 @@ tests/cases/compiler/main.ts(15,1): error TS2693: 'z1' only refers to a type, but is being used as a value here. tests/cases/compiler/main.ts(21,4): error TS2339: Property 'a' does not exist on type '() => any'. tests/cases/compiler/main.ts(23,4): error TS2339: Property 'a' does not exist on type 'typeof Foo'. -tests/cases/compiler/main.ts(27,8): error TS1192: Module '"interface"' has no default export. -tests/cases/compiler/main.ts(28,8): error TS1192: Module '"variable"' has no default export. -tests/cases/compiler/main.ts(29,8): error TS1192: Module '"interface-variable"' has no default export. -tests/cases/compiler/main.ts(30,8): error TS1192: Module '"module"' has no default export. -tests/cases/compiler/main.ts(31,8): error TS1192: Module '"interface-module"' has no default export. -tests/cases/compiler/main.ts(32,8): error TS1192: Module '"variable-module"' has no default export. -tests/cases/compiler/main.ts(33,8): error TS1192: Module '"function"' has no default export. -tests/cases/compiler/main.ts(34,8): error TS1192: Module '"function-module"' has no default export. -tests/cases/compiler/main.ts(35,8): error TS1192: Module '"class"' has no default export. -tests/cases/compiler/main.ts(36,8): error TS1192: Module '"class-module"' has no default export. +tests/cases/compiler/main.ts(27,8): error TS1259: Module '"interface"' can only be default-imported using the 'esModuleInterop' flag +tests/cases/compiler/main.ts(28,8): error TS1259: Module '"variable"' can only be default-imported using the 'esModuleInterop' flag +tests/cases/compiler/main.ts(29,8): error TS1259: Module '"interface-variable"' can only be default-imported using the 'esModuleInterop' flag +tests/cases/compiler/main.ts(30,8): error TS1259: Module '"module"' can only be default-imported using the 'esModuleInterop' flag +tests/cases/compiler/main.ts(31,8): error TS1259: Module '"interface-module"' can only be default-imported using the 'esModuleInterop' flag +tests/cases/compiler/main.ts(32,8): error TS1259: Module '"variable-module"' can only be default-imported using the 'esModuleInterop' flag +tests/cases/compiler/main.ts(33,8): error TS1259: Module '"function"' can only be default-imported using the 'esModuleInterop' flag +tests/cases/compiler/main.ts(34,8): error TS1259: Module '"function-module"' can only be default-imported using the 'esModuleInterop' flag +tests/cases/compiler/main.ts(35,8): error TS1259: Module '"class"' can only be default-imported using the 'esModuleInterop' flag +tests/cases/compiler/main.ts(36,8): error TS1259: Module '"class-module"' can only be default-imported using the 'esModuleInterop' flag tests/cases/compiler/main.ts(39,21): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export. tests/cases/compiler/main.ts(45,21): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export. tests/cases/compiler/main.ts(47,21): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export. @@ -76,34 +76,44 @@ tests/cases/compiler/main.ts(106,15): error TS2498: Module '"class-module"' uses // default import import x1 from "interface"; ~~ -!!! error TS1192: Module '"interface"' has no default export. +!!! error TS1259: Module '"interface"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:6:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. import x2 from "variable"; ~~ -!!! error TS1192: Module '"variable"' has no default export. +!!! error TS1259: Module '"variable"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:14:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. import x3 from "interface-variable"; ~~ -!!! error TS1192: Module '"interface-variable"' has no default export. +!!! error TS1259: Module '"interface-variable"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:26:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. import x4 from "module"; ~~ -!!! error TS1192: Module '"module"' has no default export. +!!! error TS1259: Module '"module"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:34:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. import x5 from "interface-module"; ~~ -!!! error TS1192: Module '"interface-module"' has no default export. +!!! error TS1259: Module '"interface-module"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:46:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. import x6 from "variable-module"; ~~ -!!! error TS1192: Module '"variable-module"' has no default export. +!!! error TS1259: Module '"variable-module"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:60:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. import x7 from "function"; ~~ -!!! error TS1192: Module '"function"' has no default export. +!!! error TS1259: Module '"function"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:65:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. import x8 from "function-module"; ~~ -!!! error TS1192: Module '"function-module"' has no default export. +!!! error TS1259: Module '"function-module"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:74:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. import x9 from "class"; ~~ -!!! error TS1192: Module '"class"' has no default export. +!!! error TS1259: Module '"class"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:82:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. import x0 from "class-module"; ~~ -!!! error TS1192: Module '"class-module"' has no default export. +!!! error TS1259: Module '"class-module"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/modules.d.ts:94:5: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. // namespace import import * as y1 from "interface"; diff --git a/tests/baselines/reference/es6ImportDefaultBindingInEs5.errors.txt b/tests/baselines/reference/es6ImportDefaultBindingInEs5.errors.txt index 604b27fd9c..924792bf98 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingInEs5.errors.txt +++ b/tests/baselines/reference/es6ImportDefaultBindingInEs5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/es6ImportDefaultBindingInEs5_1.ts(1,8): error TS1192: Module '"tests/cases/compiler/es6ImportDefaultBindingInEs5_0"' has no default export. +tests/cases/compiler/es6ImportDefaultBindingInEs5_1.ts(1,8): error TS1259: Module '"tests/cases/compiler/es6ImportDefaultBindingInEs5_0"' can only be default-imported using the 'esModuleInterop' flag ==== tests/cases/compiler/es6ImportDefaultBindingInEs5_0.ts (0 errors) ==== @@ -8,4 +8,5 @@ tests/cases/compiler/es6ImportDefaultBindingInEs5_1.ts(1,8): error TS1192: Modul ==== tests/cases/compiler/es6ImportDefaultBindingInEs5_1.ts (1 errors) ==== import defaultBinding from "./es6ImportDefaultBindingInEs5_0"; ~~~~~~~~~~~~~~ -!!! error TS1192: Module '"tests/cases/compiler/es6ImportDefaultBindingInEs5_0"' has no default export. \ No newline at end of file +!!! error TS1259: Module '"tests/cases/compiler/es6ImportDefaultBindingInEs5_0"' can only be default-imported using the 'esModuleInterop' flag +!!! related TS2594 tests/cases/compiler/es6ImportDefaultBindingInEs5_0.ts:2:1: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag. \ No newline at end of file diff --git a/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.errors.txt b/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.errors.txt new file mode 100644 index 0000000000..d59ec8b42c --- /dev/null +++ b/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.errors.txt @@ -0,0 +1,15 @@ +/bar.ts(1,1): error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead. +/foo.ts(1,8): error TS1259: Module '"/bar"' can only be default-imported using the 'allowSyntheticDefaultImports' flag + + +==== /bar.ts (1 errors) ==== + export = bar; + ~~~~~~~~~~~~~ +!!! error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead. + function bar() {} + +==== /foo.ts (1 errors) ==== + import bar from './bar'; + ~~~ +!!! error TS1259: Module '"/bar"' can only be default-imported using the 'allowSyntheticDefaultImports' flag +!!! related TS2594 /bar.ts:1:1: This module is declared with using 'export =', and can only be used with a default import when using the 'allowSyntheticDefaultImports' flag. \ No newline at end of file diff --git a/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.js b/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.js new file mode 100644 index 0000000000..5d433cba79 --- /dev/null +++ b/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/exportAssignmentWithoutAllowSyntheticDefaultImportsError.ts] //// + +//// [bar.ts] +export = bar; +function bar() {} + +//// [foo.ts] +import bar from './bar'; + +//// [bar.js] +function bar() { } +//// [foo.js] diff --git a/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.symbols b/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.symbols new file mode 100644 index 0000000000..8dca8faecf --- /dev/null +++ b/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.symbols @@ -0,0 +1,11 @@ +=== /bar.ts === +export = bar; +>bar : Symbol(bar, Decl(bar.ts, 0, 13)) + +function bar() {} +>bar : Symbol(bar, Decl(bar.ts, 0, 13)) + +=== /foo.ts === +import bar from './bar'; +>bar : Symbol(bar, Decl(foo.ts, 0, 6)) + diff --git a/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.types b/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.types new file mode 100644 index 0000000000..d5c22d809c --- /dev/null +++ b/tests/baselines/reference/exportAssignmentWithoutAllowSyntheticDefaultImportsError.types @@ -0,0 +1,11 @@ +=== /bar.ts === +export = bar; +>bar : () => void + +function bar() {} +>bar : () => void + +=== /foo.ts === +import bar from './bar'; +>bar : any + diff --git a/tests/cases/compiler/exportAssignmentWithoutAllowSyntheticDefaultImportsError.ts b/tests/cases/compiler/exportAssignmentWithoutAllowSyntheticDefaultImportsError.ts new file mode 100644 index 0000000000..8513a6bdb6 --- /dev/null +++ b/tests/cases/compiler/exportAssignmentWithoutAllowSyntheticDefaultImportsError.ts @@ -0,0 +1,8 @@ +// @module: es2015 + +// @Filename: /bar.ts +export = bar; +function bar() {} + +// @Filename: /foo.ts +import bar from './bar'; \ No newline at end of file