Skip to content

Commit a6fed14

Browse files
committed
Resolve module from typeRoot if the resolution doesnt succeed
1 parent aff834f commit a6fed14

6 files changed

+60
-42
lines changed

src/compiler/moduleNameResolver.ts

+27-5
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,9 @@ function nodeModuleNameResolverWorker(features: NodeResolutionFeatures, moduleNa
15521552
}
15531553
resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
15541554
}
1555+
if (extensions & Extensions.Declaration) {
1556+
resolved ??= resolveFromTypeRoot(moduleName, state);
1557+
}
15551558
if (!resolved) return undefined;
15561559

15571560
let resolvedValue = resolved.value;
@@ -2770,20 +2773,20 @@ export function classicNameResolver(moduleName: string, containingFile: string,
27702773
if (!isExternalModuleNameRelative(moduleName)) {
27712774
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, /*mode*/ undefined, redirectedReference);
27722775
// Climb up parent directories looking for a module.
2773-
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
2776+
let resolved = forEachAncestorDirectory(containingDirectory, directory => {
27742777
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, state);
27752778
if (resolutionFromCache) {
27762779
return resolutionFromCache;
27772780
}
27782781
const searchName = normalizePath(combinePaths(directory, moduleName));
27792782
return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, /*onlyRecordFailures*/ false, state));
27802783
});
2781-
if (resolved) {
2782-
return resolved;
2783-
}
2784+
if (resolved) return resolved;
27842785
if (extensions & (Extensions.TypeScript | Extensions.Declaration)) {
27852786
// If we didn't find the file normally, look it up in @types.
2786-
return loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, containingDirectory, state);
2787+
resolved = loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, containingDirectory, state);
2788+
if (extensions & Extensions.Declaration) resolved ??= resolveFromTypeRoot(moduleName, state);
2789+
return resolved;
27872790
}
27882791
}
27892792
else {
@@ -2793,6 +2796,25 @@ export function classicNameResolver(moduleName: string, containingFile: string,
27932796
}
27942797
}
27952798

2799+
function resolveFromTypeRoot(moduleName: string, state: ModuleResolutionState) {
2800+
if (!state.compilerOptions.typeRoots) return;
2801+
for (const typeRoot of state.compilerOptions.typeRoots) {
2802+
const candidate = combinePaths(typeRoot, moduleName);
2803+
const directoryExists = directoryProbablyExists(typeRoot, state.host);
2804+
if (!directoryExists && state.traceEnabled) {
2805+
trace(state.host, Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, typeRoot);
2806+
}
2807+
const resolvedFromFile = loadModuleFromFile(Extensions.Declaration, candidate, !directoryExists, state);
2808+
if (resolvedFromFile) {
2809+
const packageDirectory = parseNodeModuleFromPath(resolvedFromFile.path);
2810+
const packageInfo = packageDirectory ? getPackageJsonInfo(packageDirectory, /*onlyRecordFailures*/ false, state) : undefined;
2811+
return toSearchResult(withPackageId(packageInfo, resolvedFromFile));
2812+
}
2813+
const resolved = loadNodeModuleFromDirectory(Extensions.Declaration, candidate, !directoryExists, state);
2814+
if (resolved) return toSearchResult(resolved);
2815+
}
2816+
}
2817+
27962818
/**
27972819
* A host may load a module from a global cache of typings.
27982820
* This is the minumum code needed to expose that functionality; the rest is in the host.

tests/baselines/reference/moduleResolutionAsTypeReferenceDirective.errors.txt

-14
This file was deleted.

tests/baselines/reference/moduleResolutionAsTypeReferenceDirective.trace.json

+9-5
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33
"Module resolution kind is not specified, using 'NodeJs'.",
44
"Loading module 'phaser' from 'node_modules' folder, target file types: TypeScript, Declaration.",
55
"Directory '/node_modules' does not exist, skipping all lookups in it.",
6-
"Loading module 'phaser' from 'node_modules' folder, target file types: JavaScript.",
7-
"Directory '/node_modules' does not exist, skipping all lookups in it.",
8-
"======== Module name 'phaser' was not resolved. ========",
9-
"======== Resolving type reference directive 'phaser', containing file '/__inferred type names__.ts', root directory '/typings'. ========",
10-
"Resolving with primary search path '/typings'.",
116
"File '/typings/phaser.d.ts' does not exist.",
127
"Found 'package.json' at '/typings/phaser/package.json'.",
138
"'package.json' does not have a 'typesVersions' field.",
149
"'package.json' does not have a 'typings' field.",
1510
"'package.json' has 'types' field 'types/phaser.d.ts' that references '/typings/phaser/types/phaser.d.ts'.",
1611
"File '/typings/phaser/types/phaser.d.ts' exist - use it as a name resolution result.",
1712
"Resolving real path for '/typings/phaser/types/phaser.d.ts', result '/typings/phaser/types/phaser.d.ts'.",
13+
"======== Module name 'phaser' was successfully resolved to '/typings/phaser/types/phaser.d.ts' with Package ID 'phaser/types/phaser.d.ts@1.2.3'. ========",
14+
"======== Resolving type reference directive 'phaser', containing file '/__inferred type names__.ts', root directory '/typings'. ========",
15+
"Resolving with primary search path '/typings'.",
16+
"File '/typings/phaser.d.ts' does not exist.",
17+
"File '/typings/phaser/package.json' exists according to earlier cached lookups.",
18+
"'package.json' does not have a 'typings' field.",
19+
"'package.json' has 'types' field 'types/phaser.d.ts' that references '/typings/phaser/types/phaser.d.ts'.",
20+
"File '/typings/phaser/types/phaser.d.ts' exist - use it as a name resolution result.",
21+
"Resolving real path for '/typings/phaser/types/phaser.d.ts', result '/typings/phaser/types/phaser.d.ts'.",
1822
"======== Type reference directive 'phaser' was successfully resolved to '/typings/phaser/types/phaser.d.ts' with Package ID 'phaser/types/phaser.d.ts@1.2.3', primary: true. ========"
1923
]

tests/baselines/reference/moduleResolutionAsTypeReferenceDirective.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
=== /a.ts ===
22
import { a2 } from "phaser";
3-
>a2 : any
3+
>a2 : number
44

55
=== /typings/phaser/types/phaser.d.ts ===
66
export const a2: number;

tests/baselines/reference/moduleResolutionAsTypeReferenceDirectiveAmbient.trace.json

+9-5
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33
"Module resolution kind is not specified, using 'NodeJs'.",
44
"Loading module 'phaser' from 'node_modules' folder, target file types: TypeScript, Declaration.",
55
"Directory '/node_modules' does not exist, skipping all lookups in it.",
6-
"Loading module 'phaser' from 'node_modules' folder, target file types: JavaScript.",
7-
"Directory '/node_modules' does not exist, skipping all lookups in it.",
8-
"======== Module name 'phaser' was not resolved. ========",
9-
"======== Resolving type reference directive 'phaser', containing file '/__inferred type names__.ts', root directory '/typings'. ========",
10-
"Resolving with primary search path '/typings'.",
116
"File '/typings/phaser.d.ts' does not exist.",
127
"Found 'package.json' at '/typings/phaser/package.json'.",
138
"'package.json' does not have a 'typesVersions' field.",
149
"'package.json' does not have a 'typings' field.",
1510
"'package.json' has 'types' field 'types/phaser.d.ts' that references '/typings/phaser/types/phaser.d.ts'.",
1611
"File '/typings/phaser/types/phaser.d.ts' exist - use it as a name resolution result.",
1712
"Resolving real path for '/typings/phaser/types/phaser.d.ts', result '/typings/phaser/types/phaser.d.ts'.",
13+
"======== Module name 'phaser' was successfully resolved to '/typings/phaser/types/phaser.d.ts' with Package ID 'phaser/types/phaser.d.ts@1.2.3'. ========",
14+
"======== Resolving type reference directive 'phaser', containing file '/__inferred type names__.ts', root directory '/typings'. ========",
15+
"Resolving with primary search path '/typings'.",
16+
"File '/typings/phaser.d.ts' does not exist.",
17+
"File '/typings/phaser/package.json' exists according to earlier cached lookups.",
18+
"'package.json' does not have a 'typings' field.",
19+
"'package.json' has 'types' field 'types/phaser.d.ts' that references '/typings/phaser/types/phaser.d.ts'.",
20+
"File '/typings/phaser/types/phaser.d.ts' exist - use it as a name resolution result.",
21+
"Resolving real path for '/typings/phaser/types/phaser.d.ts', result '/typings/phaser/types/phaser.d.ts'.",
1822
"======== Type reference directive 'phaser' was successfully resolved to '/typings/phaser/types/phaser.d.ts' with Package ID 'phaser/types/phaser.d.ts@1.2.3', primary: true. ========"
1923
]

tests/baselines/reference/tsserver/resolutionCache/when-resolves-to-ambient-module.js

+14-12
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ Info 17 [00:00:50.000] DirectoryWatcher:: Added:: WatchInfo: /user/username/pr
8585
Info 18 [00:00:51.000] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/src/node_modules 1 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: Failed Lookup Locations
8686
Info 19 [00:00:52.000] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules 1 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: Failed Lookup Locations
8787
Info 20 [00:00:53.000] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules 1 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: Failed Lookup Locations
88-
Info 21 [00:00:54.000] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/src/typings 1 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: Type roots
89-
Info 22 [00:00:55.000] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/src/typings 1 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: Type roots
90-
Info 23 [00:00:56.000] Finishing updateGraphWorker: Project: /user/username/projects/myproject/src/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
91-
Info 24 [00:00:57.000] Project '/user/username/projects/myproject/src/tsconfig.json' (Configured)
92-
Info 25 [00:00:58.000] Files (5)
88+
Info 21 [00:00:54.000] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/src/typings 1 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: Failed Lookup Locations
89+
Info 22 [00:00:55.000] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/src/typings 1 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: Failed Lookup Locations
90+
Info 23 [00:00:56.000] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/src/typings 1 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: Type roots
91+
Info 24 [00:00:57.000] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/src/typings 1 undefined Project: /user/username/projects/myproject/src/tsconfig.json WatchType: Type roots
92+
Info 25 [00:00:58.000] Finishing updateGraphWorker: Project: /user/username/projects/myproject/src/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
93+
Info 26 [00:00:59.000] Project '/user/username/projects/myproject/src/tsconfig.json' (Configured)
94+
Info 27 [00:01:00.000] Files (5)
9395
/a/lib/lib.d.ts
9496
/user/username/projects/myproject/src/somefolder/module1.ts
9597
/user/username/projects/myproject/src/somefolder/srcfile.ts
@@ -109,11 +111,11 @@ Info 25 [00:00:58.000] Files (5)
109111
typings/node.d.ts
110112
Matched by default include pattern '**/*'
111113

112-
Info 26 [00:00:59.000] -----------------------------------------------
113-
Info 27 [00:01:00.000] Project '/user/username/projects/myproject/src/tsconfig.json' (Configured)
114-
Info 27 [00:01:01.000] Files (5)
114+
Info 28 [00:01:01.000] -----------------------------------------------
115+
Info 29 [00:01:02.000] Project '/user/username/projects/myproject/src/tsconfig.json' (Configured)
116+
Info 29 [00:01:03.000] Files (5)
115117

116-
Info 27 [00:01:02.000] -----------------------------------------------
117-
Info 27 [00:01:03.000] Open files:
118-
Info 27 [00:01:04.000] FileName: /user/username/projects/myproject/src/somefolder/srcfile.ts ProjectRootPath: /user/username/projects/myproject
119-
Info 27 [00:01:05.000] Projects: /user/username/projects/myproject/src/tsconfig.json
118+
Info 29 [00:01:04.000] -----------------------------------------------
119+
Info 29 [00:01:05.000] Open files:
120+
Info 29 [00:01:06.000] FileName: /user/username/projects/myproject/src/somefolder/srcfile.ts ProjectRootPath: /user/username/projects/myproject
121+
Info 29 [00:01:07.000] Projects: /user/username/projects/myproject/src/tsconfig.json

0 commit comments

Comments
 (0)