fix(36909): wrong error message when trying to named-import an export (#36925)

This commit is contained in:
Alexander T
2020-03-28 21:16:50 +02:00
committed by GitHub
parent 6d7539a211
commit 96f01227d4
39 changed files with 520 additions and 18 deletions

View File

@@ -2551,7 +2551,7 @@ namespace ts {
);
}
else {
reportNonExportedMember(name, declarationName, moduleSymbol, moduleName);
reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName);
}
}
}
@@ -2560,27 +2560,50 @@ namespace ts {
}
}
function reportNonExportedMember(name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void {
function reportNonExportedMember(node: ImportDeclaration | ExportDeclaration, name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void {
const localSymbol = moduleSymbol.valueDeclaration.locals?.get(name.escapedText);
const exports = moduleSymbol.exports;
if (localSymbol) {
const exportedSymbol = exports && !exports.has(InternalSymbolName.ExportEquals)
? find(symbolsToArray(exports), symbol => !!getSymbolIfSameReference(symbol, localSymbol))
: undefined;
const diagnostic = exportedSymbol
? error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, symbolToString(exportedSymbol))
: error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName);
const exportedEqualsSymbol = exports?.get(InternalSymbolName.ExportEquals);
if (exportedEqualsSymbol) {
getSymbolIfSameReference(exportedEqualsSymbol, localSymbol) ? reportInvalidImportEqualsExportMember(node, name, declarationName, moduleName) :
error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
}
else {
const exportedSymbol = exports ? find(symbolsToArray(exports), symbol => !!getSymbolIfSameReference(symbol, localSymbol)) : undefined;
const diagnostic = exportedSymbol ? error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, symbolToString(exportedSymbol)) :
error(name, Diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName);
addRelatedInfo(diagnostic,
...map(localSymbol.declarations, (decl, index) =>
createDiagnosticForNode(decl, index === 0 ? Diagnostics._0_is_declared_here : Diagnostics.and_here, declarationName)));
addRelatedInfo(diagnostic,
...map(localSymbol.declarations, (decl, index) =>
createDiagnosticForNode(decl, index === 0 ? Diagnostics._0_is_declared_here : Diagnostics.and_here, declarationName)));
}
}
else {
error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
}
}
function reportInvalidImportEqualsExportMember(node: ImportDeclaration | ExportDeclaration, name: Identifier, declarationName: string, moduleName: string) {
if (moduleKind >= ModuleKind.ES2015) {
const message = compilerOptions.esModuleInterop ? Diagnostics._0_can_only_be_imported_by_using_a_default_import :
Diagnostics._0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import;
error(name, message, declarationName);
}
else {
if (isInJSFile(node)) {
const message = compilerOptions.esModuleInterop ? Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import :
Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import;
error(name, message, declarationName);
}
else {
const message = compilerOptions.esModuleInterop ? Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import :
Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import;
error(name, message, declarationName, declarationName, moduleName);
}
}
}
function getTargetOfImportSpecifier(node: ImportSpecifier, dontResolveAlias: boolean): Symbol | undefined {
const resolved = getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias);
markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);

View File

@@ -2321,6 +2321,22 @@
"category": "Error",
"code": 2594
},
"'{0}' can only be imported by using a default import.": {
"category": "Error",
"code": 2595
},
"'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import.": {
"category": "Error",
"code": 2596
},
"'{0}' can only be imported by using a 'require' call or by using a default import.": {
"category": "Error",
"code": 2597
},
"'{0}' can only be imported by using a 'require' call or by turning on the 'esModuleInterop' flag and using a default import.": {
"category": "Error",
"code": 2598
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
@@ -2385,6 +2401,14 @@
"category": "Error",
"code": 2615
},
"'{0}' can only be imported by using 'import {1} = require({2})' or a default import.": {
"category": "Error",
"code": 2616
},
"'{0}' can only be imported by using 'import {1} = require({2})' or by turning on the 'esModuleInterop' flag and using a default import.": {
"category": "Error",
"code": 2617
},
"Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": {
"category": "Error",

View File

@@ -1,5 +1,5 @@
tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(1,10): error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported.
tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(2,10): error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported.
tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(1,10): error TS2617: 'a' can only be imported by using 'import a = require("./es6ImportNamedImportNoNamedExports_0")' or by turning on the 'esModuleInterop' flag and using a default import.
tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(2,10): error TS2617: 'a' can only be imported by using 'import a = require("./es6ImportNamedImportNoNamedExports_0")' or by turning on the 'esModuleInterop' flag and using a default import.
==== tests/cases/compiler/es6ImportNamedImportNoNamedExports_0.ts (0 errors) ====
@@ -9,9 +9,7 @@ tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts(2,10): error TS2459
==== tests/cases/compiler/es6ImportNamedImportNoNamedExports_1.ts (2 errors) ====
import { a } from "./es6ImportNamedImportNoNamedExports_0";
~
!!! error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported.
!!! related TS2728 tests/cases/compiler/es6ImportNamedImportNoNamedExports_0.ts:1:5: 'a' is declared here.
!!! error TS2617: 'a' can only be imported by using 'import a = require("./es6ImportNamedImportNoNamedExports_0")' or by turning on the 'esModuleInterop' flag and using a default import.
import { a as x } from "./es6ImportNamedImportNoNamedExports_0";
~
!!! error TS2459: Module '"./es6ImportNamedImportNoNamedExports_0"' declares 'a' locally, but it is not exported.
!!! related TS2728 tests/cases/compiler/es6ImportNamedImportNoNamedExports_0.ts:1:5: 'a' is declared here.
!!! error TS2617: 'a' can only be imported by using 'import a = require("./es6ImportNamedImportNoNamedExports_0")' or by turning on the 'esModuleInterop' flag and using a default import.

View File

@@ -0,0 +1,17 @@
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.
tests/cases/compiler/b.js(1,10): error TS2596: 'Foo' can only be imported by turning on the 'esModuleInterop' flag and using a default import.
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.
==== tests/cases/compiler/a.ts (1 errors) ====
class Foo {}
export = Foo;
~~~~~~~~~~~~~
!!! error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
==== tests/cases/compiler/b.js (2 errors) ====
import { Foo } from './a';
~~~
!!! error TS2596: 'Foo' can only be imported by turning on the 'esModuleInterop' flag and using a default import.
~~~~~
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
export = Foo;
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
=== tests/cases/compiler/b.js ===
import { Foo } from './a';
>Foo : Symbol(Foo, Decl(b.js, 0, 8))

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Foo
export = Foo;
>Foo : Foo
=== tests/cases/compiler/b.js ===
import { Foo } from './a';
>Foo : any

View File

@@ -0,0 +1,17 @@
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.
tests/cases/compiler/b.js(1,10): error TS2595: 'Foo' can only be imported by using a default import.
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.
==== tests/cases/compiler/a.ts (1 errors) ====
class Foo {}
export = Foo;
~~~~~~~~~~~~~
!!! error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
==== tests/cases/compiler/b.js (2 errors) ====
import { Foo } from './a';
~~~
!!! error TS2595: 'Foo' can only be imported by using a default import.
~~~~~
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
export = Foo;
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
=== tests/cases/compiler/b.js ===
import { Foo } from './a';
>Foo : Symbol(Foo, Decl(b.js, 0, 8))

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Foo
export = Foo;
>Foo : Foo
=== tests/cases/compiler/b.js ===
import { Foo } from './a';
>Foo : any

View File

@@ -0,0 +1,14 @@
tests/cases/compiler/b.ts(1,10): error TS2617: 'Foo' can only be imported by using 'import Foo = require("./a")' or by turning on the 'esModuleInterop' flag and using a default import.
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.
==== tests/cases/compiler/a.ts (0 errors) ====
class Foo {}
export = Foo;
==== tests/cases/compiler/b.ts (2 errors) ====
import { Foo } from './a';
~~~
!!! error TS2617: 'Foo' can only be imported by using 'import Foo = require("./a")' or by turning on the 'esModuleInterop' flag and using a default import.
~~~~~
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.

View File

@@ -0,0 +1,20 @@
//// [tests/cases/compiler/importNonExportedMember4.ts] ////
//// [a.ts]
class Foo {}
export = Foo;
//// [b.ts]
import { Foo } from './a';
//// [a.js]
"use strict";
var Foo = /** @class */ (function () {
function Foo() {
}
return Foo;
}());
module.exports = Foo;
//// [b.js]
"use strict";
exports.__esModule = true;

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
export = Foo;
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
=== tests/cases/compiler/b.ts ===
import { Foo } from './a';
>Foo : Symbol(Foo, Decl(b.ts, 0, 8))

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Foo
export = Foo;
>Foo : Foo
=== tests/cases/compiler/b.ts ===
import { Foo } from './a';
>Foo : any

View File

@@ -0,0 +1,14 @@
tests/cases/compiler/b.ts(1,10): error TS2616: 'Foo' can only be imported by using 'import Foo = require("./a")' or a default import.
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.
==== tests/cases/compiler/a.ts (0 errors) ====
class Foo {}
export = Foo;
==== tests/cases/compiler/b.ts (2 errors) ====
import { Foo } from './a';
~~~
!!! error TS2616: 'Foo' can only be imported by using 'import Foo = require("./a")' or a default import.
~~~~~
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.

View File

@@ -0,0 +1,20 @@
//// [tests/cases/compiler/importNonExportedMember5.ts] ////
//// [a.ts]
class Foo {}
export = Foo;
//// [b.ts]
import { Foo } from './a';
//// [a.js]
"use strict";
var Foo = /** @class */ (function () {
function Foo() {
}
return Foo;
}());
module.exports = Foo;
//// [b.js]
"use strict";
exports.__esModule = true;

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
export = Foo;
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
=== tests/cases/compiler/b.ts ===
import { Foo } from './a';
>Foo : Symbol(Foo, Decl(b.ts, 0, 8))

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Foo
export = Foo;
>Foo : Foo
=== tests/cases/compiler/b.ts ===
import { Foo } from './a';
>Foo : any

View File

@@ -0,0 +1,17 @@
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.
tests/cases/compiler/b.ts(1,10): error TS2596: 'Foo' can only be imported by turning on the 'esModuleInterop' flag and using a default import.
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.
==== tests/cases/compiler/a.ts (1 errors) ====
class Foo {}
export = Foo;
~~~~~~~~~~~~~
!!! error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
==== tests/cases/compiler/b.ts (2 errors) ====
import { Foo } from './a';
~~~
!!! error TS2596: 'Foo' can only be imported by turning on the 'esModuleInterop' flag and using a default import.
~~~~~
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.

View File

@@ -0,0 +1,16 @@
//// [tests/cases/compiler/importNonExportedMember6.ts] ////
//// [a.ts]
class Foo {}
export = Foo;
//// [b.ts]
import { Foo } from './a';
//// [a.js]
var Foo = /** @class */ (function () {
function Foo() {
}
return Foo;
}());
//// [b.js]

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
export = Foo;
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
=== tests/cases/compiler/b.ts ===
import { Foo } from './a';
>Foo : Symbol(Foo, Decl(b.ts, 0, 8))

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Foo
export = Foo;
>Foo : Foo
=== tests/cases/compiler/b.ts ===
import { Foo } from './a';
>Foo : any

View File

@@ -0,0 +1,17 @@
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.
tests/cases/compiler/b.ts(1,10): error TS2595: 'Foo' can only be imported by using a default import.
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.
==== tests/cases/compiler/a.ts (1 errors) ====
class Foo {}
export = Foo;
~~~~~~~~~~~~~
!!! error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.
==== tests/cases/compiler/b.ts (2 errors) ====
import { Foo } from './a';
~~~
!!! error TS2595: 'Foo' can only be imported by using a default import.
~~~~~
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.

View File

@@ -0,0 +1,16 @@
//// [tests/cases/compiler/importNonExportedMember7.ts] ////
//// [a.ts]
class Foo {}
export = Foo;
//// [b.ts]
import { Foo } from './a';
//// [a.js]
var Foo = /** @class */ (function () {
function Foo() {
}
return Foo;
}());
//// [b.js]

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
export = Foo;
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
=== tests/cases/compiler/b.ts ===
import { Foo } from './a';
>Foo : Symbol(Foo, Decl(b.ts, 0, 8))

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Foo
export = Foo;
>Foo : Foo
=== tests/cases/compiler/b.ts ===
import { Foo } from './a';
>Foo : any

View File

@@ -0,0 +1,15 @@
tests/cases/compiler/b.js(1,10): error TS2598: 'Foo' can only be imported by using a 'require' call or by turning on the 'esModuleInterop' flag and using a default import.
tests/cases/compiler/b.js(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.
==== tests/cases/compiler/a.ts (0 errors) ====
class Foo {}
export = Foo;
==== tests/cases/compiler/b.js (2 errors) ====
import { Foo } from './a';
~~~
!!! error TS2598: 'Foo' can only be imported by using a 'require' call or by turning on the 'esModuleInterop' flag and using a default import.
~~~~~
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
export = Foo;
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
=== tests/cases/compiler/b.js ===
import { Foo } from './a';
>Foo : Symbol(Foo, Decl(b.js, 0, 8))

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Foo
export = Foo;
>Foo : Foo
=== tests/cases/compiler/b.js ===
import { Foo } from './a';
>Foo : any

View File

@@ -0,0 +1,14 @@
tests/cases/compiler/b.js(1,10): error TS2597: 'Foo' can only be imported by using a 'require' call or by using a default import.
tests/cases/compiler/b.js(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.
==== tests/cases/compiler/a.ts (0 errors) ====
class Foo {}
export = Foo;
==== tests/cases/compiler/b.js (2 errors) ====
import { Foo } from './a';
~~~
!!! error TS2597: 'Foo' can only be imported by using a 'require' call or by using a default import.
~~~~~
!!! error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
export = Foo;
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
=== tests/cases/compiler/b.js ===
import { Foo } from './a';
>Foo : Symbol(Foo, Decl(b.js, 0, 8))

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/a.ts ===
class Foo {}
>Foo : Foo
export = Foo;
>Foo : Foo
=== tests/cases/compiler/b.js ===
import { Foo } from './a';
>Foo : any

View File

@@ -0,0 +1,12 @@
// @esModuleInterop: false
// @module: es2015
// @checkJs: true
// @allowJs: true
// @noEmit: true
// @Filename: a.ts
class Foo {}
export = Foo;
// @Filename: b.js
import { Foo } from './a';

View File

@@ -0,0 +1,12 @@
// @esModuleInterop: true
// @module: es2015
// @checkJs: true
// @allowJs: true
// @noEmit: true
// @Filename: a.ts
class Foo {}
export = Foo;
// @Filename: b.js
import { Foo } from './a';

View File

@@ -0,0 +1,9 @@
// @esModuleInterop: false
// @module: commonjs
// @Filename: a.ts
class Foo {}
export = Foo;
// @Filename: b.ts
import { Foo } from './a';

View File

@@ -0,0 +1,9 @@
// @esModuleInterop: true
// @module: commonjs
// @Filename: a.ts
class Foo {}
export = Foo;
// @Filename: b.ts
import { Foo } from './a';

View File

@@ -0,0 +1,9 @@
// @module: es2015
// @esModuleInterop: false
// @Filename: a.ts
class Foo {}
export = Foo;
// @Filename: b.ts
import { Foo } from './a';

View File

@@ -0,0 +1,9 @@
// @module: es2015
// @esModuleInterop: true
// @Filename: a.ts
class Foo {}
export = Foo;
// @Filename: b.ts
import { Foo } from './a';

View File

@@ -0,0 +1,12 @@
// @esModuleInterop: false
// @module: commonjs
// @checkJs: true
// @allowJs: true
// @noEmit: true
// @Filename: a.ts
class Foo {}
export = Foo;
// @Filename: b.js
import { Foo } from './a';

View File

@@ -0,0 +1,12 @@
// @esModuleInterop: true
// @module: commonjs
// @checkJs: true
// @allowJs: true
// @noEmit: true
// @Filename: a.ts
class Foo {}
export = Foo;
// @Filename: b.js
import { Foo } from './a';