Skip to content

Commit 29039de

Browse files
committed
Have declaration file auto imports default to extensionless instead
1 parent f04f1b5 commit 29039de

File tree

2 files changed

+21
-14
lines changed

2 files changed

+21
-14
lines changed

src/compiler/moduleSpecifiers.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ function getPreferences(
6060
}
6161
switch (preferredEnding) {
6262
case ModuleSpecifierEnding.JsExtension: return [ModuleSpecifierEnding.JsExtension, ModuleSpecifierEnding.Minimal, ModuleSpecifierEnding.Index];
63-
case ModuleSpecifierEnding.TsExtension: return [ModuleSpecifierEnding.TsExtension, ModuleSpecifierEnding.TsExtension, ModuleSpecifierEnding.Minimal, ModuleSpecifierEnding.Index];
63+
case ModuleSpecifierEnding.TsExtension: return [ModuleSpecifierEnding.TsExtension, ModuleSpecifierEnding.Minimal, ModuleSpecifierEnding.JsExtension, ModuleSpecifierEnding.Index];
6464
case ModuleSpecifierEnding.Index: return [ModuleSpecifierEnding.Index, ModuleSpecifierEnding.Minimal, ModuleSpecifierEnding.JsExtension];
6565
case ModuleSpecifierEnding.Minimal: return [ModuleSpecifierEnding.Minimal, ModuleSpecifierEnding.Index, ModuleSpecifierEnding.JsExtension];
6666
default: Debug.assertNever(preferredEnding);
@@ -367,7 +367,7 @@ function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOpt
367367
return fromPaths;
368368
}
369369

370-
const maybeNonRelative = fromPaths === undefined && baseUrl !== undefined ? processEnding(relativeToBaseUrl, ending, compilerOptions) : fromPaths;
370+
const maybeNonRelative = fromPaths === undefined && baseUrl !== undefined ? processEnding(relativeToBaseUrl, allowedEndings, compilerOptions) : fromPaths;
371371
if (!maybeNonRelative) {
372372
return relativePath;
373373
}
@@ -655,7 +655,7 @@ function tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: MapLike<rea
655655
// sorted among the others for a particular value of `importModuleSpecifierEnding`.
656656
const candidates: { ending: ModuleSpecifierEnding | undefined, value: string }[] = allowedEndings.map(ending => ({
657657
ending,
658-
value: processEnding(relativeToBaseUrl, ending, compilerOptions)
658+
value: processEnding(relativeToBaseUrl, [ending], compilerOptions)
659659
}));
660660
if (tryGetExtensionFromPath(pattern)) {
661661
candidates.push({ ending: undefined, value: relativeToBaseUrl });
@@ -692,7 +692,7 @@ function tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: MapLike<rea
692692
// `ModuleSpecifierEnding.Index` result, which should already be in the list of candidates if `Minimal` was. (Note: the assumption here is
693693
// that every module resolution mode that supports dropping extensions also supports dropping `/index`. Like literally
694694
// everything else in this file, this logic needs to be updated if that's not true in some future module resolution mode.)
695-
return ending !== ModuleSpecifierEnding.Minimal || value === processEnding(relativeToBaseUrl, ending, compilerOptions, host);
695+
return ending !== ModuleSpecifierEnding.Minimal || value === processEnding(relativeToBaseUrl, [ending], compilerOptions, host);
696696
}
697697
}
698698

@@ -767,7 +767,7 @@ function tryGetModuleNameFromExports(options: CompilerOptions, targetFilePath: s
767767
return undefined;
768768
}
769769

770-
function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, ending: ModuleSpecifierEnding, compilerOptions: CompilerOptions): string | undefined {
770+
function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileName: string, sourceDirectory: string, getCanonicalFileName: (file: string) => string, allowedEndings: readonly ModuleSpecifierEnding[], compilerOptions: CompilerOptions): string | undefined {
771771
const normalizedTargetPaths = getPathsRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName);
772772
if (normalizedTargetPaths === undefined) {
773773
return undefined;
@@ -781,7 +781,7 @@ function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileNam
781781
if (!shortest) {
782782
return undefined;
783783
}
784-
return processEnding(shortest, ending, compilerOptions);
784+
return processEnding(shortest, allowedEndings, compilerOptions);
785785
}
786786

787787
function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCanonicalFileName, sourceDirectory }: Info, importingSourceFile: SourceFile, host: ModuleSpecifierResolutionHost, options: CompilerOptions, userPreferences: UserPreferences, packageNameOnly?: boolean, overrideMode?: ResolutionMode): string | undefined {
@@ -823,7 +823,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan
823823
// try with next level of directory
824824
packageRootIndex = path.indexOf(directorySeparator, packageRootIndex + 1);
825825
if (packageRootIndex === -1) {
826-
moduleSpecifier = processEnding(moduleFileName, allowedEndings[0], options, host);
826+
moduleSpecifier = processEnding(moduleFileName, allowedEndings, options, host);
827827
break;
828828
}
829829
}
@@ -936,7 +936,7 @@ function getPathsRelativeToRootDirs(path: string, rootDirs: readonly string[], g
936936
});
937937
}
938938

939-
function processEnding(fileName: string, ending: ModuleSpecifierEnding, options: CompilerOptions, host?: ModuleSpecifierResolutionHost): string {
939+
function processEnding(fileName: string, allowedEndings: readonly ModuleSpecifierEnding[], options: CompilerOptions, host?: ModuleSpecifierResolutionHost): string {
940940
if (fileExtensionIsOneOf(fileName, [Extension.Json, Extension.Mjs, Extension.Cjs])) {
941941
return fileName;
942942
}
@@ -950,7 +950,7 @@ function processEnding(fileName: string, ending: ModuleSpecifierEnding, options:
950950
return noExtension + getJSExtensionForFile(fileName, options);
951951
}
952952

953-
switch (ending) {
953+
switch (allowedEndings[0]) {
954954
case ModuleSpecifierEnding.Minimal:
955955
const withoutIndex = removeSuffix(noExtension, "/index");
956956
if (host && withoutIndex !== noExtension && tryGetAnyFileFromPath(host, withoutIndex)) {
@@ -965,10 +965,17 @@ function processEnding(fileName: string, ending: ModuleSpecifierEnding, options:
965965
return noExtension + getJSExtensionForFile(fileName, options);
966966
case ModuleSpecifierEnding.TsExtension:
967967
// For now, we don't know if this import is going to be type-only, which means we don't
968-
// know if a .d.ts extension is valid, so use the .js extension.
969-
return isDeclarationFileName(fileName) ? noExtension + getJSExtensionForFile(fileName, options) : fileName;
968+
// know if a .d.ts extension is valid, so use no extension or a .js extension
969+
if (isDeclarationFileName(fileName)) {
970+
const extensionlessPriority = allowedEndings.findIndex(e => e === ModuleSpecifierEnding.Minimal || e === ModuleSpecifierEnding.Index);
971+
const jsPriority = allowedEndings.indexOf(ModuleSpecifierEnding.JsExtension);
972+
return extensionlessPriority !== -1 && extensionlessPriority < jsPriority
973+
? noExtension
974+
: noExtension + getJSExtensionForFile(fileName, options);
975+
}
976+
return fileName;
970977
default:
971-
return Debug.assertNever(ending);
978+
return Debug.assertNever(allowedEndings[0]);
972979
}
973980
}
974981

tests/baselines/reference/autoImportAllowTsExtensions3.baseline.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import { Component } from "./Component.tsx";
66

77
## From completions
88

9-
- `fromDecl` from `"./decl.js"`
9+
- `fromDecl` from `"./decl"`
1010
- `fromLocal` from `"./local.ts"`
1111

1212
```ts
1313
import { Component } from "./Component.tsx";
14-
import { fromDecl } from "./decl.js";
14+
import { fromDecl } from "./decl";
1515
fromDecl
1616
```
1717

0 commit comments

Comments
 (0)