Skip to content

Commit 575baf5

Browse files
authored
Support auto-import from paths alias without baseUrl (#40546)
1 parent ec36d73 commit 575baf5

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

src/compiler/moduleNameResolver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,15 +788,15 @@ namespace ts {
788788
}
789789

790790
function tryLoadModuleUsingPathsIfEligible(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState) {
791-
const { baseUrl, paths, pathsBasePath } = state.compilerOptions;
791+
const { baseUrl, paths } = state.compilerOptions;
792792
if (paths && !pathIsRelative(moduleName)) {
793793
if (state.traceEnabled) {
794794
if (baseUrl) {
795795
trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
796796
}
797797
trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
798798
}
799-
const baseDirectory = baseUrl ?? Debug.checkDefined(pathsBasePath || state.host.getCurrentDirectory?.(), "Encountered 'paths' without a 'baseUrl', config file, or host 'getCurrentDirectory'.");
799+
const baseDirectory = getPathsBasePath(state.compilerOptions, state.host)!; // Always defined when 'paths' is defined
800800
return tryLoadModuleUsingPaths(extensions, moduleName, baseDirectory, paths, loader, /*onlyRecordFailures*/ false, state);
801801
}
802802
}

src/compiler/moduleSpecifiers.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ namespace ts.moduleSpecifiers {
8282
const info = getInfo(importingSourceFileName, host);
8383
const modulePaths = getAllModulePaths(importingSourceFileName, toFileName, host);
8484
return firstDefined(modulePaths, modulePath => tryGetModuleNameAsNodeModule(modulePath, info, host, compilerOptions)) ||
85-
getLocalModuleSpecifier(toFileName, info, compilerOptions, preferences);
85+
getLocalModuleSpecifier(toFileName, info, compilerOptions, host, preferences);
8686
}
8787

8888
/** Returns an import for each symlink and for the realpath. */
@@ -121,7 +121,7 @@ namespace ts.moduleSpecifiers {
121121
}
122122

123123
if (!specifier && !modulePath.isRedirect) {
124-
const local = getLocalModuleSpecifier(modulePath.path, info, compilerOptions, preferences);
124+
const local = getLocalModuleSpecifier(modulePath.path, info, compilerOptions, host, preferences);
125125
if (pathIsBareSpecifier(local)) {
126126
pathsSpecifiers = append(pathsSpecifiers, local);
127127
}
@@ -156,16 +156,17 @@ namespace ts.moduleSpecifiers {
156156
return { getCanonicalFileName, sourceDirectory };
157157
}
158158

159-
function getLocalModuleSpecifier(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): string {
159+
function getLocalModuleSpecifier(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, { ending, relativePreference }: Preferences): string {
160160
const { baseUrl, paths, rootDirs, bundledPackageName } = compilerOptions;
161161

162162
const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) ||
163163
removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
164-
if (!baseUrl || relativePreference === RelativePreference.Relative) {
164+
if (!baseUrl && !paths || relativePreference === RelativePreference.Relative) {
165165
return relativePath;
166166
}
167167

168-
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName);
168+
const baseDirectory = getPathsBasePath(compilerOptions, host) || baseUrl!;
169+
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseDirectory, getCanonicalFileName);
169170
if (!relativeToBaseUrl) {
170171
return relativePath;
171172
}

src/compiler/utilities.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4087,6 +4087,12 @@ namespace ts {
40874087
return options.outFile || options.out;
40884088
}
40894089

4090+
/** Returns 'undefined' if and only if 'options.paths' is undefined. */
4091+
export function getPathsBasePath(options: CompilerOptions, host: { getCurrentDirectory?(): string }) {
4092+
if (!options.paths) return undefined;
4093+
return options.baseUrl ?? Debug.checkDefined(options.pathsBasePath || host.getCurrentDirectory?.(), "Encountered 'paths' without a 'baseUrl', config file, or host 'getCurrentDirectory'.");
4094+
}
4095+
40904096
export interface EmitFileNames {
40914097
jsFilePath?: string | undefined;
40924098
sourceMapFilePath?: string | undefined;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: tsconfig.json
4+
//// {
5+
//// "compilerOptions": {
6+
//// "module": "commonjs",
7+
//// "paths": {
8+
//// "@app/*": ["lib/*"]
9+
//// }
10+
//// }
11+
//// }
12+
13+
// @Filename: index.ts
14+
//// utils/**/
15+
16+
// @Filename: lib/utils.ts
17+
//// export const utils = {};
18+
19+
20+
goTo.marker("");
21+
verify.importFixAtPosition([`import { utils } from "@app/utils";\n\nutils`]);

0 commit comments

Comments
 (0)