Skip to content

Commit c1a0946

Browse files
committed
fix(36909): wrong error message when trying to named-import an export
1 parent cf24c4f commit c1a0946

39 files changed

+517
-17
lines changed

src/compiler/checker.ts

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2509,7 +2509,7 @@ namespace ts {
25092509
);
25102510
}
25112511
else {
2512-
reportNonExportedMember(name, declarationName, moduleSymbol, moduleName);
2512+
reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName);
25132513
}
25142514
}
25152515
}
@@ -2518,21 +2518,46 @@ namespace ts {
25182518
}
25192519
}
25202520

2521-
function reportNonExportedMember(name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void {
2521+
function reportNonExportedMember(node: ImportDeclaration | ExportDeclaration, name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void {
25222522
const localSymbol = moduleSymbol.valueDeclaration.locals?.get(name.escapedText);
25232523
const exports = moduleSymbol.exports;
25242524

25252525
if (localSymbol) {
2526-
const exportedSymbol = exports && !exports.has(InternalSymbolName.ExportEquals)
2527-
? find(symbolsToArray(exports), symbol => !!getSymbolIfSameReference(symbol, localSymbol))
2528-
: undefined;
2529-
const diagnostic = exportedSymbol
2530-
? error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, symbolToString(exportedSymbol))
2531-
: error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName);
2526+
const exportedEqualsSymbol = exports?.get(InternalSymbolName.ExportEquals);
2527+
if (exportedEqualsSymbol) {
2528+
if (getSymbolIfSameReference(exportedEqualsSymbol, localSymbol)) {
2529+
if (moduleKind >= ModuleKind.ES2015) {
2530+
compilerOptions.allowSyntheticDefaultImports
2531+
? error(name, Diagnostics._0_can_only_be_imported_by_using_a_default_import, declarationName)
2532+
: error(name, Diagnostics._0_can_only_be_imported_by_turning_on_the_allowSyntheticDefaultImports_flag_and_using_a_default_import, declarationName);
2533+
}
2534+
if (moduleKind < ModuleKind.ES2015) {
2535+
if (isInJSFile(node)) {
2536+
compilerOptions.allowSyntheticDefaultImports
2537+
? error(name, Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import, declarationName)
2538+
: error(name, Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_allowSyntheticDefaultImports_flag_and_using_a_default_import, declarationName);
2539+
}
2540+
else {
2541+
compilerOptions.allowSyntheticDefaultImports
2542+
? error(name, Diagnostics._0_can_only_be_imported_by_using_import_Foo_require_or_a_default_import, declarationName)
2543+
: error(name, Diagnostics._0_can_only_be_imported_by_using_import_Foo_require_or_by_turning_on_the_allowSyntheticDefaultImports_flag_and_using_a_default_import, declarationName);
2544+
}
2545+
}
2546+
}
2547+
else {
2548+
error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
2549+
}
2550+
}
2551+
else {
2552+
const exportedSymbol = exports ? find(symbolsToArray(exports), symbol => !!getSymbolIfSameReference(symbol, localSymbol)) : undefined;
2553+
const diagnostic = exportedSymbol
2554+
? error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, symbolToString(exportedSymbol))
2555+
: error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName);
25322556

2533-
addRelatedInfo(diagnostic,
2534-
...map(localSymbol.declarations, (decl, index) =>
2535-
createDiagnosticForNode(decl, index === 0 ? Diagnostics._0_is_declared_here : Diagnostics.and_here, declarationName)));
2557+
addRelatedInfo(diagnostic,
2558+
...map(localSymbol.declarations, (decl, index) =>
2559+
createDiagnosticForNode(decl, index === 0 ? Diagnostics._0_is_declared_here : Diagnostics.and_here, declarationName)));
2560+
}
25362561
}
25372562
else {
25382563
error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);

src/compiler/diagnosticMessages.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,6 +2241,14 @@
22412241
"category": "Error",
22422242
"code": 2577
22432243
},
2244+
"'{0}' can only be imported by using 'import Foo = require(...)' or a default import.": {
2245+
"category": "Error",
2246+
"code": 2578
2247+
},
2248+
"'{0}' can only be imported by using 'import Foo = require(...)' or by turning on the 'allowSyntheticDefaultImports' flag and using a default import.": {
2249+
"category": "Error",
2250+
"code": 2579
2251+
},
22442252
"Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node`.": {
22452253
"category": "Error",
22462254
"code": 2580
@@ -2301,6 +2309,22 @@
23012309
"category": "Error",
23022310
"code": 2594
23032311
},
2312+
"'{0}' can only be imported by using a default import.": {
2313+
"category": "Error",
2314+
"code": 2595
2315+
},
2316+
"'{0}' can only be imported by turning on the 'allowSyntheticDefaultImports' flag and using a default import.": {
2317+
"category": "Error",
2318+
"code": 2596
2319+
},
2320+
"'{0}' can only be imported by using a 'require' call or by using a default import.": {
2321+
"category": "Error",
2322+
"code": 2597
2323+
},
2324+
"'{0}' can only be imported by using a 'require' call or by turning on the 'allowSyntheticDefaultImports' flag and using a default import.": {
2325+
"category": "Error",
2326+
"code": 2598
2327+
},
23042328
"JSX element attributes type '{0}' may not be a union type.": {
23052329
"category": "Error",
23062330
"code": 2600
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(1,10): error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported.
2-
tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(2,10): error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported.
1+
tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(1,10): error TS2579: 'a' can only be imported by using 'import Foo = require(...)' or by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
2+
tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(2,10): error TS2579: 'a' can only be imported by using 'import Foo = require(...)' or by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
33

44

55
==== tests/cases/compiler/es6ImportNamedImportNoNamedExports_0.ts (0 errors) ====
@@ -9,9 +9,7 @@ tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(2,10): error TS2459
99
==== tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts (2 errors) ====
1010
import { a } from "./es6ImportNamedImportNoNamedExports_0";
1111
~
12-
!!! error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported.
13-
!!! related TS2728 tests/cases/compiler/es6ImportNamedImportNoNamedExports_0.ts:1:5: 'a' is declared here.
12+
!!! error TS2579: 'a' can only be imported by using 'import Foo = require(...)' or by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
1413
import { a as x } from "./es6ImportNamedImportNoNamedExports_0";
1514
~
16-
!!! error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported.
17-
!!! related TS2728 tests/cases/compiler/es6ImportNamedImportNoNamedExports_0.ts:1:5: 'a' is declared here.
15+
!!! error TS2579: 'a' can only be imported by using 'import Foo = require(...)' or by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
tests/cases/compiler/a.ts(2,1): error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
2+
tests/cases/compiler/b.js(1,10): error TS2596: 'Foo' can only be imported by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
3+
tests/cases/compiler/b.js(1,21): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.
4+
5+
6+
==== tests/cases/compiler/a.ts (1 errors) ====
7+
class Foo {}
8+
export = Foo;
9+
~~~~~~~~~~~~~
10+
!!! error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
11+
12+
==== tests/cases/compiler/b.js (2 errors) ====
13+
import { Foo } from './a';
14+
~~~
15+
!!! error TS2596: 'Foo' can only be imported by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
16+
~~~~~
17+
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
4+
5+
export = Foo;
6+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
7+
8+
=== tests/cases/compiler/b.js ===
9+
import { Foo } from './a';
10+
>Foo : Symbol(Foo, Decl(b.js, 0, 8))
11+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Foo
4+
5+
export = Foo;
6+
>Foo : Foo
7+
8+
=== tests/cases/compiler/b.js ===
9+
import { Foo } from './a';
10+
>Foo : any
11+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
tests/cases/compiler/a.ts(2,1): error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
2+
tests/cases/compiler/b.js(1,10): error TS2595: 'Foo' can only be imported by using a default import.
3+
tests/cases/compiler/b.js(1,21): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.
4+
5+
6+
==== tests/cases/compiler/a.ts (1 errors) ====
7+
class Foo {}
8+
export = Foo;
9+
~~~~~~~~~~~~~
10+
!!! error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
11+
12+
==== tests/cases/compiler/b.js (2 errors) ====
13+
import { Foo } from './a';
14+
~~~
15+
!!! error TS2595: 'Foo' can only be imported by using a default import.
16+
~~~~~
17+
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
4+
5+
export = Foo;
6+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
7+
8+
=== tests/cases/compiler/b.js ===
9+
import { Foo } from './a';
10+
>Foo : Symbol(Foo, Decl(b.js, 0, 8))
11+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Foo
4+
5+
export = Foo;
6+
>Foo : Foo
7+
8+
=== tests/cases/compiler/b.js ===
9+
import { Foo } from './a';
10+
>Foo : any
11+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
tests/cases/compiler/b.ts(1,10): error TS2579: 'Foo' can only be imported by using 'import Foo = require(...)' or by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
2+
tests/cases/compiler/b.ts(1,21): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.
3+
4+
5+
==== tests/cases/compiler/a.ts (0 errors) ====
6+
class Foo {}
7+
export = Foo;
8+
9+
==== tests/cases/compiler/b.ts (2 errors) ====
10+
import { Foo } from './a';
11+
~~~
12+
!!! error TS2579: 'Foo' can only be imported by using 'import Foo = require(...)' or by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
13+
~~~~~
14+
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//// [tests/cases/compiler/importNonExportedMember4.ts] ////
2+
3+
//// [a.ts]
4+
class Foo {}
5+
export = Foo;
6+
7+
//// [b.ts]
8+
import { Foo } from './a';
9+
10+
//// [a.js]
11+
"use strict";
12+
var Foo = /** @class */ (function () {
13+
function Foo() {
14+
}
15+
return Foo;
16+
}());
17+
module.exports = Foo;
18+
//// [b.js]
19+
"use strict";
20+
exports.__esModule = true;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
4+
5+
export = Foo;
6+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
7+
8+
=== tests/cases/compiler/b.ts ===
9+
import { Foo } from './a';
10+
>Foo : Symbol(Foo, Decl(b.ts, 0, 8))
11+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Foo
4+
5+
export = Foo;
6+
>Foo : Foo
7+
8+
=== tests/cases/compiler/b.ts ===
9+
import { Foo } from './a';
10+
>Foo : any
11+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
tests/cases/compiler/b.ts(1,10): error TS2578: 'Foo' can only be imported by using 'import Foo = require(...)' or a default import.
2+
tests/cases/compiler/b.ts(1,21): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.
3+
4+
5+
==== tests/cases/compiler/a.ts (0 errors) ====
6+
class Foo {}
7+
export = Foo;
8+
9+
==== tests/cases/compiler/b.ts (2 errors) ====
10+
import { Foo } from './a';
11+
~~~
12+
!!! error TS2578: 'Foo' can only be imported by using 'import Foo = require(...)' or a default import.
13+
~~~~~
14+
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//// [tests/cases/compiler/importNonExportedMember5.ts] ////
2+
3+
//// [a.ts]
4+
class Foo {}
5+
export = Foo;
6+
7+
//// [b.ts]
8+
import { Foo } from './a';
9+
10+
//// [a.js]
11+
"use strict";
12+
var Foo = /** @class */ (function () {
13+
function Foo() {
14+
}
15+
return Foo;
16+
}());
17+
module.exports = Foo;
18+
//// [b.js]
19+
"use strict";
20+
exports.__esModule = true;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
4+
5+
export = Foo;
6+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
7+
8+
=== tests/cases/compiler/b.ts ===
9+
import { Foo } from './a';
10+
>Foo : Symbol(Foo, Decl(b.ts, 0, 8))
11+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Foo
4+
5+
export = Foo;
6+
>Foo : Foo
7+
8+
=== tests/cases/compiler/b.ts ===
9+
import { Foo } from './a';
10+
>Foo : any
11+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
tests/cases/compiler/a.ts(2,1): error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
2+
tests/cases/compiler/b.ts(1,10): error TS2596: 'Foo' can only be imported by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
3+
tests/cases/compiler/b.ts(1,21): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.
4+
5+
6+
==== tests/cases/compiler/a.ts (1 errors) ====
7+
class Foo {}
8+
export = Foo;
9+
~~~~~~~~~~~~~
10+
!!! error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
11+
12+
==== tests/cases/compiler/b.ts (2 errors) ====
13+
import { Foo } from './a';
14+
~~~
15+
!!! error TS2596: 'Foo' can only be imported by turning on the 'allowSyntheticDefaultImports' flag and using a default import.
16+
~~~~~
17+
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [tests/cases/compiler/importNonExportedMember6.ts] ////
2+
3+
//// [a.ts]
4+
class Foo {}
5+
export = Foo;
6+
7+
//// [b.ts]
8+
import { Foo } from './a';
9+
10+
//// [a.js]
11+
var Foo = /** @class */ (function () {
12+
function Foo() {
13+
}
14+
return Foo;
15+
}());
16+
//// [b.js]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
4+
5+
export = Foo;
6+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
7+
8+
=== tests/cases/compiler/b.ts ===
9+
import { Foo } from './a';
10+
>Foo : Symbol(Foo, Decl(b.ts, 0, 8))
11+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/a.ts ===
2+
class Foo {}
3+
>Foo : Foo
4+
5+
export = Foo;
6+
>Foo : Foo
7+
8+
=== tests/cases/compiler/b.ts ===
9+
import { Foo } from './a';
10+
>Foo : any
11+

0 commit comments

Comments
 (0)