Skip to content

Commit 359c8b1

Browse files
author
Andy Hanson
committed
Don't allow ".d.ts" extension in an import either.
1 parent 0f134ed commit 359c8b1

File tree

9 files changed

+46
-43
lines changed

9 files changed

+46
-43
lines changed

Diff for: src/compiler/checker.ts

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

13671367
if (moduleNotFoundError) {
13681368
// report errors only if it was requested
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));
1369+
const tsExtension = tryExtractTypeScriptExtension(moduleName);
1370+
if (tsExtension) {
1371+
const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
1372+
error(moduleReferenceLiteral, diag, tsExtension, removeExtension(moduleName, tsExtension));
13731373
}
13741374
else {
13751375
error(moduleReferenceLiteral, moduleNotFoundError, moduleName);

Diff for: src/compiler/core.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1198,8 +1198,7 @@ namespace ts {
11981198
/**
11991199
* List of supported extensions in order of file resolution precedence.
12001200
*/
1201-
export const supportedTypeScriptExtensionsNonDts = [".ts", ".tsx"];
1202-
export const supportedTypeScriptExtensions = supportedTypeScriptExtensionsNonDts.concat([".d.ts"]);
1201+
export const supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"];
12031202
export const supportedJavascriptExtensions = [".js", ".jsx"];
12041203
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
12051204

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-
"An import path should not end with a '{0}' extension. Consider importing '{1}' instead.": {
1954+
"An import path cannot end with a '{0}' extension. Consider importing '{1}' instead.": {
19551955
"category": "Error",
19561956
"code": 2691
19571957
},

Diff for: src/compiler/program.ts

+4-12
Original file line numberDiff line numberDiff line change
@@ -669,17 +669,7 @@ namespace ts {
669669
* in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
670670
*/
671671
function loadModuleFromFile(candidate: string, extensions: string[], failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
672-
// If the candidate already has an extension load that or quit.
673-
if (hasTypeScriptFileExtension(candidate)) {
674-
// Don't allow `.ts` to appear at the end
675-
if (!fileExtensionIs(candidate, ".d.ts")) {
676-
return undefined;
677-
}
678-
return tryFile(candidate, failedLookupLocation, onlyRecordFailures, state);
679-
}
680-
681-
// Next, try adding an extension.
682-
// We don't allow an import of "foo.ts" to be matched by "foo.ts.ts", but we do allow "foo.js" to be matched by "foo.js.ts".
672+
// First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
683673
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state);
684674
if (resolvedByAddingExtension) {
685675
return resolvedByAddingExtension;
@@ -736,7 +726,9 @@ namespace ts {
736726
}
737727
const typesFile = tryReadTypesSection(packageJsonPath, candidate, state);
738728
if (typesFile) {
739-
const result = loadModuleFromFile(typesFile, extensions, failedLookupLocation, !directoryProbablyExists(getDirectoryPath(typesFile), state.host), state);
729+
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(typesFile), state.host);
730+
// The package.json "typings" property must specify the file with extension, so just try that exact filename.
731+
const result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures, state);
740732
if (result) {
741733
return result;
742734
}

Diff for: src/compiler/utilities.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -2727,9 +2727,11 @@ namespace ts {
27272727
}
27282728

27292729
/** 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));
2730+
export function tryExtractTypeScriptExtension(fileName: string): string | undefined {
2731+
return find(supportedTypescriptExtensionsWithDtsFirst, extension => fileExtensionIs(fileName, extension));
27322732
}
2733+
// Must have '.d.ts' first because if '.ts' goes first, that will be detected as the extension instead of '.d.ts'.
2734+
const supportedTypescriptExtensionsWithDtsFirst = supportedTypeScriptExtensions.slice().reverse();
27332735

27342736
/**
27352737
* Replace each instance of non-ascii characters by one, two, three, or four escape sequences

Diff for: src/harness/compilerRunner.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class CompilerBaselineRunner extends RunnerBase {
5252
private makeUnitName(name: string, root: string) {
5353
const path = ts.toPath(name, root, (fileName) => Harness.Compiler.getCanonicalFileName(fileName));
5454
const pathStart = ts.toPath(Harness.IO.getCurrentDirectory(), "", (fileName) => Harness.Compiler.getCanonicalFileName(fileName));
55-
return path.replace(pathStart, "/");
55+
return pathStart === "" ? path : path.replace(pathStart, "/");
5656
};
5757

5858
public checkTestCodeOutput(fileName: string) {
+19-13
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
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.
1+
tests/cases/compiler/user.ts(1,15): error TS2691: An import path cannot end with a '.ts' extension. Consider importing './x' instead.
2+
tests/cases/compiler/user.ts(2,15): error TS2691: An import path cannot end with a '.tsx' extension. Consider importing './y' instead.
3+
tests/cases/compiler/user.ts(3,15): error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './z' instead.
34

45

5-
==== tests/cases/compiler/user.ts (2 errors) ====
6-
// '.ts' extension is OK in a reference
7-
///<reference path="./x.ts"/>
6+
==== tests/cases/compiler/x.ts (0 errors) ====
7+
export default 0;
8+
9+
==== tests/cases/compiler/y.tsx (0 errors) ====
10+
export default 0;
11+
12+
==== tests/cases/compiler/z.d.ts (0 errors) ====
13+
declare const x: number;
14+
export default x;
815

16+
==== tests/cases/compiler/user.ts (3 errors) ====
917
import x from "./x.ts";
1018
~~~~~~~~
11-
!!! error TS2691: An import path should not end with a '.ts' extension. Consider importing './x' instead.
19+
!!! error TS2691: An import path cannot end with a '.ts' extension. Consider importing './x' instead.
1220
import y from "./y.tsx";
1321
~~~~~~~~~
14-
!!! error TS2691: An import path should not end with a '.tsx' extension. Consider importing './y' instead.
22+
!!! error TS2691: An import path cannot end with a '.tsx' extension. Consider importing './y' instead.
23+
import z from "./z.d.ts";
24+
~~~~~~~~~~
25+
!!! error TS2691: An import path cannot end with a '.d.ts' extension. Consider importing './z' instead.
1526

1627
// Making sure the suggested fixes are valid:
1728
import x2 from "./x";
1829
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) ====
24-
export default 0;
30+
import z2 from "./z";
2531

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

+6-5
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@ export default 0;
66
//// [y.tsx]
77
export default 0;
88

9+
//// [z.d.ts]
10+
declare const x: number;
11+
export default x;
12+
913
//// [user.ts]
10-
// '.ts' extension is OK in a reference
11-
///<reference path="./x.ts"/>
12-
1314
import x from "./x.ts";
1415
import y from "./y.tsx";
16+
import z from "./z.d.ts";
1517

1618
// Making sure the suggested fixes are valid:
1719
import x2 from "./x";
1820
import y2 from "./y";
21+
import z2 from "./z";
1922

2023

2124
//// [x.js]
@@ -27,6 +30,4 @@ exports["default"] = 0;
2730
exports.__esModule = true;
2831
exports["default"] = 0;
2932
//// [user.js]
30-
// '.ts' extension is OK in a reference
31-
///<reference path="./x.ts"/>
3233
"use strict";

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ export default 0;
44
// @filename: y.tsx
55
export default 0;
66

7-
// @filename: user.ts
8-
// '.ts' extension is OK in a reference
9-
///<reference path="./x.ts"/>
7+
// @filename: z.d.ts
8+
declare const x: number;
9+
export default x;
1010

11+
// @filename: user.ts
1112
import x from "./x.ts";
1213
import y from "./y.tsx";
14+
import z from "./z.d.ts";
1315

1416
// Making sure the suggested fixes are valid:
1517
import x2 from "./x";
1618
import y2 from "./y";
19+
import z2 from "./z";

0 commit comments

Comments
 (0)