Skip to content

Commit 0f134ed

Browse files
author
Andy Hanson
committed
Improve error message
1 parent 2821d98 commit 0f134ed

File tree

7 files changed

+71
-22
lines changed

7 files changed

+71
-22
lines changed

Diff for: src/compiler/checker.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1366,8 +1366,10 @@ namespace ts {
13661366

13671367
if (moduleNotFoundError) {
13681368
// report errors only if it was requested
1369-
if (hasTypeScriptFileExtensionNonDts(moduleName)) {
1370-
error(moduleReferenceLiteral, Diagnostics.Module_name_should_not_include_a_ts_extension_Colon_0, moduleName);
1369+
const nonDtsExtension = tryExtractTypeScriptExtensionNonDts(moduleName);
1370+
if (nonDtsExtension) {
1371+
const diag = Diagnostics.An_import_path_should_not_end_with_a_0_extension_Consider_importing_1_instead;
1372+
error(moduleReferenceLiteral, diag, nonDtsExtension, removeExtension(moduleName, nonDtsExtension));
13711373
}
13721374
else {
13731375
error(moduleReferenceLiteral, moduleNotFoundError, moduleName);

Diff for: src/compiler/core.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ namespace ts {
9393
return undefined;
9494
}
9595

96+
/** Works like Array.prototype.find. */
97+
export function find<T>(array: T[], predicate: (element: T, index: number) => boolean): T | undefined {
98+
for (let i = 0, len = array.length; i < len; i++) {
99+
const value = array[i];
100+
if (predicate(value, i)) {
101+
return value;
102+
}
103+
}
104+
return undefined;
105+
}
106+
96107
export function contains<T>(array: T[], value: T): boolean {
97108
if (array) {
98109
for (const v of array) {
@@ -941,7 +952,7 @@ namespace ts {
941952
* [^./] # matches everything up to the first . character (excluding directory seperators)
942953
* (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension
943954
*/
944-
const singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*";
955+
const singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*";
945956
const singleAsteriskRegexFragmentOther = "[^/]*";
946957

947958
export function getRegularExpressionForWildcard(specs: string[], basePath: string, usage: "files" | "directories" | "exclude") {
@@ -1271,8 +1282,12 @@ namespace ts {
12711282
return path;
12721283
}
12731284

1274-
export function tryRemoveExtension(path: string, extension: string): string {
1275-
return fileExtensionIs(path, extension) ? path.substring(0, path.length - extension.length) : undefined;
1285+
export function tryRemoveExtension(path: string, extension: string): string | undefined {
1286+
return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined;
1287+
}
1288+
1289+
export function removeExtension(path: string, extension: string): string {
1290+
return path.substring(0, path.length - extension.length);
12761291
}
12771292

12781293
export function isJsxOrTsxExtension(ext: string): boolean {

Diff for: src/compiler/diagnosticMessages.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1951,7 +1951,7 @@
19511951
"category": "Error",
19521952
"code": 2690
19531953
},
1954-
"Module name should not include a '.ts' extension: '{0}'.": {
1954+
"An import path should not end with a '{0}' extension. Consider importing '{1}' instead.": {
19551955
"category": "Error",
19561956
"code": 2691
19571957
},

Diff for: src/compiler/utilities.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -2726,8 +2726,9 @@ namespace ts {
27262726
return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension));
27272727
}
27282728

2729-
export function hasTypeScriptFileExtensionNonDts(fileName: string) {
2730-
return forEach(supportedTypeScriptExtensionsNonDts, extension => fileExtensionIs(fileName, extension));
2729+
/** Return ".ts" or ".tsx" if that is the extension. */
2730+
export function tryExtractTypeScriptExtensionNonDts(fileName: string): string | undefined {
2731+
return find(supportedTypeScriptExtensionsNonDts, extension => fileExtensionIs(fileName, extension));
27312732
}
27322733

27332734
/**
+17-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
1-
tests/cases/compiler/user.ts(4,15): error TS2690: Module name should not include a '.ts' extension: './m.ts'.
1+
tests/cases/compiler/user.ts(4,15): error TS2691: An import path should not end with a '.ts' extension. Consider importing './x' instead.
2+
tests/cases/compiler/user.ts(5,15): error TS2691: An import path should not end with a '.tsx' extension. Consider importing './y' instead.
23

34

4-
==== tests/cases/compiler/user.ts (1 errors) ====
5+
==== tests/cases/compiler/user.ts (2 errors) ====
56
// '.ts' extension is OK in a reference
6-
///<reference path="./m.ts"/>
7+
///<reference path="./x.ts"/>
78

8-
import x from "./m.ts";
9+
import x from "./x.ts";
910
~~~~~~~~
10-
!!! error TS2690: Module name should not include a '.ts' extension: './m.ts'.
11+
!!! error TS2691: An import path should not end with a '.ts' extension. Consider importing './x' instead.
12+
import y from "./y.tsx";
13+
~~~~~~~~~
14+
!!! error TS2691: An import path should not end with a '.tsx' extension. Consider importing './y' instead.
1115

12-
==== tests/cases/compiler/m.ts (0 errors) ====
16+
// Making sure the suggested fixes are valid:
17+
import x2 from "./x";
18+
import y2 from "./y";
19+
20+
==== tests/cases/compiler/x.ts (0 errors) ====
21+
export default 0;
22+
23+
==== tests/cases/compiler/y.tsx (0 errors) ====
1324
export default 0;
1425

Diff for: tests/baselines/reference/moduleResolutionNoTs.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
//// [tests/cases/compiler/moduleResolutionNoTs.ts] ////
22

3-
//// [m.ts]
3+
//// [x.ts]
4+
export default 0;
5+
6+
//// [y.tsx]
47
export default 0;
58

69
//// [user.ts]
710
// '.ts' extension is OK in a reference
8-
///<reference path="./m.ts"/>
11+
///<reference path="./x.ts"/>
12+
13+
import x from "./x.ts";
14+
import y from "./y.tsx";
915

10-
import x from "./m.ts";
16+
// Making sure the suggested fixes are valid:
17+
import x2 from "./x";
18+
import y2 from "./y";
1119

1220

13-
//// [m.js]
21+
//// [x.js]
22+
"use strict";
23+
exports.__esModule = true;
24+
exports["default"] = 0;
25+
//// [y.js]
1426
"use strict";
1527
exports.__esModule = true;
1628
exports["default"] = 0;
1729
//// [user.js]
1830
// '.ts' extension is OK in a reference
19-
///<reference path="./m.ts"/>
31+
///<reference path="./x.ts"/>
2032
"use strict";

Diff for: tests/cases/compiler/moduleResolutionNoTs.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1-
// @filename: m.ts
1+
// @filename: x.ts
2+
export default 0;
3+
4+
// @filename: y.tsx
25
export default 0;
36

47
// @filename: user.ts
58
// '.ts' extension is OK in a reference
6-
///<reference path="./m.ts"/>
9+
///<reference path="./x.ts"/>
10+
11+
import x from "./x.ts";
12+
import y from "./y.tsx";
713

8-
import x from "./m.ts";
14+
// Making sure the suggested fixes are valid:
15+
import x2 from "./x";
16+
import y2 from "./y";

0 commit comments

Comments
 (0)