Skip to content

Commit 12a8b18

Browse files
committed
Always resolve package.json exports in type reference directives
1 parent abc37af commit 12a8b18

21 files changed

+298
-289
lines changed

src/compiler/moduleNameResolver.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -579,19 +579,13 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
579579

580580
const failedLookupLocations: string[] = [];
581581
const affectingLocations: string[] = [];
582-
// Allow type reference directives to opt into `exports` resolution in any resolution mode
583-
// when a `resolution-mode` override is present.
584-
let features = getNodeResolutionFeatures(options);
585-
if (resolutionMode !== undefined) {
586-
features |= NodeResolutionFeatures.AllFeatures;
587-
}
582+
583+
let features = NodeResolutionFeatures.AllFeatures;
588584
const moduleResolution = getEmitModuleResolutionKind(options);
589585
if (resolutionMode === ModuleKind.ESNext && (ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext)) {
590586
features |= NodeResolutionFeatures.EsmMode;
591587
}
592-
const conditions = (features & NodeResolutionFeatures.Exports)
593-
? getConditions(options, resolutionMode)
594-
: [];
588+
const conditions = getConditions(options, resolutionMode);
595589
const diagnostics: Diagnostic[] = [];
596590
const moduleResolutionState: ModuleResolutionState = {
597591
compilerOptions: options,
@@ -677,7 +671,7 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
677671
}
678672
}
679673
return resolvedTypeScriptOnly(
680-
loadNodeModuleFromDirectory(Extensions.Declaration, candidate, !directoryExists, moduleResolutionState),
674+
loadModuleFromSpecificNodeModulesDirectory(Extensions.Declaration, typeReferenceDirectiveName, typeRoot, directoryExists, moduleResolutionState, /*cache*/ undefined, redirectedReference, /*disableFileLookup*/ true),
681675
);
682676
});
683677
}
@@ -3051,7 +3045,7 @@ function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, mod
30513045
}
30523046
}
30533047

3054-
function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, moduleName: string, nodeModulesDirectory: string, nodeModulesDirectoryExists: boolean, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): Resolved | undefined {
3048+
function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, moduleName: string, nodeModulesDirectory: string, nodeModulesDirectoryExists: boolean, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, disableFileLookup?: boolean): Resolved | undefined {
30553049
const candidate = normalizePath(combinePaths(nodeModulesDirectory, moduleName));
30563050
const { packageName, rest } = parsePackageName(moduleName);
30573051
const packageDirectory = combinePaths(nodeModulesDirectory, packageName);
@@ -3066,7 +3060,7 @@ function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, modu
30663060
!hasProperty((rootPackageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state))?.contents.packageJsonContent ?? emptyArray, "exports")
30673061
)
30683062
) {
3069-
const fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state);
3063+
const fromFile = !disableFileLookup && loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state);
30703064
if (fromFile) {
30713065
return noPackageId(fromFile);
30723066
}
@@ -3083,7 +3077,7 @@ function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, modu
30833077
}
30843078

30853079
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => {
3086-
let pathAndExtension = (rest || !(state.features & NodeResolutionFeatures.EsmMode)) && loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) ||
3080+
let pathAndExtension = (rest || !(state.features & NodeResolutionFeatures.EsmMode)) && !disableFileLookup && loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) ||
30873081
loadNodeModuleFromDirectoryWorker(
30883082
extensions,
30893083
candidate,

src/harness/fourslashImpl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2352,7 +2352,7 @@ export class TestState {
23522352
}
23532353

23542354
public baselineSyntacticAndSemanticDiagnostics() {
2355-
const files = ts.filter(this.getCompilerTestFiles(), f => !ts.endsWith(f.unitName, ".json"));
2355+
const files = ts.filter(this.getCompilerTestFiles(), f => !ts.endsWith(f.unitName, ".json") && !!this.languageService.getProgram()!.getSourceFile(f.unitName));
23562356
const result = this.getSyntacticDiagnosticBaselineText(files)
23572357
+ Harness.IO.newLine()
23582358
+ Harness.IO.newLine()

tests/baselines/reference/nodeNextImportModeImplicitIndexResolution2.errors.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
error TS2688: Cannot find type definition file for 'dedent4'.
2+
The file is in the program because:
3+
Entry point for implicit type library 'dedent4'
14
/index.cts(4,21): error TS2307: Cannot find module 'dedent4' or its corresponding type declarations.
25
/index.mts(4,21): error TS2307: Cannot find module 'dedent4' or its corresponding type declarations.
36

47

8+
!!! error TS2688: Cannot find type definition file for 'dedent4'.
9+
!!! error TS2688: The file is in the program because:
10+
!!! error TS2688: Entry point for implicit type library 'dedent4'
511
==== /node_modules/@types/dedent/package.json (0 errors) ====
612
{ "name": "@types/dedent", "version": "1.0.0", "main": "" }
713

tests/baselines/reference/reactJsxReactResolvedNodeNextEsm.trace.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535
"======== Resolving type reference directive 'react', containing file '/.src/__inferred type names__.ts', root directory '/.src/node_modules/@types,/node_modules/@types'. ========",
3636
"Resolving with primary search path '/.src/node_modules/@types, /node_modules/@types'.",
3737
"File '/.src/node_modules/@types/react/package.json' exists according to earlier cached lookups.",
38-
"'package.json' does not have a 'typings' field.",
39-
"'package.json' has 'types' field 'index.d.ts' that references '/.src/node_modules/@types/react/index.d.ts'.",
38+
"Using 'exports' subpath '.' with target './index.d.ts'.",
4039
"File '/.src/node_modules/@types/react/index.d.ts' exists - use it as a name resolution result.",
4140
"Resolving real path for '/.src/node_modules/@types/react/index.d.ts', result '/.src/node_modules/@types/react/index.d.ts'.",
4241
"======== Type reference directive 'react' was successfully resolved to '/.src/node_modules/@types/react/index.d.ts' with Package ID '@types/react/index.d.ts@0.0.1', primary: true. ========",

tests/baselines/reference/resolutionModeImportType1(moduleresolution=classic).errors.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
error TS2688: Cannot find type definition file for 'foo'.
2-
The file is in the program because:
3-
Entry point for implicit type library 'foo'
41
/app.ts(1,30): error TS2792: Cannot find module 'foo'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
52
/app.ts(2,29): error TS2792: Cannot find module 'foo'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
63
/app.ts(3,30): error TS2792: Cannot find module 'foo'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
74

85

9-
!!! error TS2688: Cannot find type definition file for 'foo'.
10-
!!! error TS2688: The file is in the program because:
11-
!!! error TS2688: Entry point for implicit type library 'foo'
126
==== /node_modules/@types/foo/package.json (0 errors) ====
137
{
148
"name": "@types/foo",

tests/baselines/reference/resolutionModeTypeOnlyImport1(moduleresolution=classic).errors.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
error TS2688: Cannot find type definition file for 'foo'.
2-
The file is in the program because:
3-
Entry point for implicit type library 'foo'
41
/app.ts(1,35): error TS2792: Cannot find module 'foo'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
52
/app.ts(2,34): error TS2792: Cannot find module 'foo'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
63
/app.ts(3,35): error TS2792: Cannot find module 'foo'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
74

85

9-
!!! error TS2688: Cannot find type definition file for 'foo'.
10-
!!! error TS2688: The file is in the program because:
11-
!!! error TS2688: Entry point for implicit type library 'foo'
126
==== /node_modules/@types/foo/package.json (0 errors) ====
137
{
148
"name": "@types/foo",

tests/baselines/reference/resolvesWithoutExportsDiagnostic1(moduleresolution=bundler).errors.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
error TS2688: Cannot find type definition file for 'bar'.
2+
The file is in the program because:
3+
Entry point for implicit type library 'bar'
14
error TS6504: File '/node_modules/bar/index.js' is a JavaScript file. Did you mean to enable the 'allowJs' option?
25
The file is in the program because:
36
Root file specified for compilation
@@ -16,6 +19,9 @@ error TS6504: File '/node_modules/foo/index.mjs' is a JavaScript file. Did you m
1619
There are types at '/node_modules/@types/bar/index.d.ts', but this result could not be resolved when respecting package.json "exports". The '@types/bar' library may need to update its package.json or typings.
1720

1821

22+
!!! error TS2688: Cannot find type definition file for 'bar'.
23+
!!! error TS2688: The file is in the program because:
24+
!!! error TS2688: Entry point for implicit type library 'bar'
1925
!!! error TS6504: File '/node_modules/bar/index.js' is a JavaScript file. Did you mean to enable the 'allowJs' option?
2026
!!! error TS6504: The file is in the program because:
2127
!!! error TS6504: Root file specified for compilation

tests/baselines/reference/resolvesWithoutExportsDiagnostic1(moduleresolution=bundler).trace.json

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,26 @@
113113
"Resolving with primary search path '/.src/node_modules/@types, /node_modules/@types'.",
114114
"Directory '/.src/node_modules/@types' does not exist, skipping all lookups in it.",
115115
"File '/node_modules/@types/bar/package.json' exists according to earlier cached lookups.",
116-
"'package.json' does not have a 'typings' field.",
117-
"'package.json' has 'types' field 'index.d.ts' that references '/node_modules/@types/bar/index.d.ts'.",
118-
"File '/node_modules/@types/bar/index.d.ts' exists - use it as a name resolution result.",
119-
"Resolving real path for '/node_modules/@types/bar/index.d.ts', result '/node_modules/@types/bar/index.d.ts'.",
120-
"======== Type reference directive 'bar' was successfully resolved to '/node_modules/@types/bar/index.d.ts' with Package ID '@types/bar/index.d.ts@1.0.0', primary: true. ========",
116+
"Entering conditional exports.",
117+
"Saw non-matching condition 'require'.",
118+
"Exiting conditional exports.",
119+
"Looking up in 'node_modules' folder, initial location '/.src'.",
120+
"Searching all ancestor node_modules directories for preferred extensions: Declaration.",
121+
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
122+
"File '/node_modules/bar/package.json' exists according to earlier cached lookups.",
123+
"Entering conditional exports.",
124+
"Matched 'exports' condition 'import'.",
125+
"Using 'exports' subpath '.' with target './index.mjs'.",
126+
"File name '/node_modules/bar/index.mjs' has a '.mjs' extension - stripping it.",
127+
"File '/node_modules/bar/index.d.mts' does not exist.",
128+
"Failed to resolve under condition 'import'.",
129+
"Saw non-matching condition 'require'.",
130+
"Exiting conditional exports.",
131+
"File '/node_modules/@types/bar/package.json' exists according to earlier cached lookups.",
132+
"Entering conditional exports.",
133+
"Saw non-matching condition 'require'.",
134+
"Exiting conditional exports.",
135+
"======== Type reference directive 'bar' was not resolved. ========",
121136
"File '/.ts/package.json' does not exist.",
122137
"File '/package.json' does not exist according to earlier cached lookups.",
123138
"======== Resolving module '@typescript/lib-es5' from '/.src/__lib_node_modules_lookup_lib.es5.d.ts__.ts'. ========",

tests/baselines/reference/resolvesWithoutExportsDiagnostic1(moduleresolution=node16).trace.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,12 @@
102102
"Resolving with primary search path '/.src/node_modules/@types, /node_modules/@types'.",
103103
"Directory '/.src/node_modules/@types' does not exist, skipping all lookups in it.",
104104
"File '/node_modules/@types/bar/package.json' exists according to earlier cached lookups.",
105-
"'package.json' does not have a 'typings' field.",
106-
"'package.json' has 'types' field 'index.d.ts' that references '/node_modules/@types/bar/index.d.ts'.",
105+
"Entering conditional exports.",
106+
"Matched 'exports' condition 'require'.",
107+
"Using 'exports' subpath '.' with target './index.d.ts'.",
107108
"File '/node_modules/@types/bar/index.d.ts' exists - use it as a name resolution result.",
109+
"Resolved under condition 'require'.",
110+
"Exiting conditional exports.",
108111
"Resolving real path for '/node_modules/@types/bar/index.d.ts', result '/node_modules/@types/bar/index.d.ts'.",
109112
"======== Type reference directive 'bar' was successfully resolved to '/node_modules/@types/bar/index.d.ts' with Package ID '@types/bar/index.d.ts@1.0.0', primary: true. ========",
110113
"File '/.ts/package.json' does not exist.",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
usage.ts(1,23): error TS2688: Cannot find type definition file for 'pkg'.
2+
3+
4+
==== node_modules/pkg/index.d.ts (0 errors) ====
5+
interface GlobalThing { a: number }
6+
==== node_modules/pkg/package.json (0 errors) ====
7+
{
8+
"name": "pkg",
9+
"types": "index.d.ts",
10+
"exports": "some-other-thing.js"
11+
}
12+
==== usage.ts (1 errors) ====
13+
/// <reference types="pkg" />
14+
~~~
15+
!!! error TS2688: Cannot find type definition file for 'pkg'.
16+
17+
const a: GlobalThing = { a: 0 };

tests/baselines/reference/tscWatch/forceConsistentCasingInFileNames/with-nodeNext-resolution.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,17 @@ File '/Users/name/projects/web/node_modules/@types/yargs/package.json' exists ac
9191
======== Resolving type reference directive 'yargs', containing file '/Users/name/projects/web/__inferred type names__.ts', root directory '/Users/name/projects/web/node_modules/@types,/Users/name/projects/node_modules/@types,/Users/name/node_modules/@types,/Users/node_modules/@types,/node_modules/@types'. ========
9292
Resolving with primary search path '/Users/name/projects/web/node_modules/@types, /Users/name/projects/node_modules/@types, /Users/name/node_modules/@types, /Users/node_modules/@types, /node_modules/@types'.
9393
File '/Users/name/projects/web/node_modules/@types/yargs/package.json' exists according to earlier cached lookups.
94-
'package.json' does not have a 'typesVersions' field.
95-
'package.json' does not have a 'typings' field.
96-
'package.json' does not have a 'types' field.
97-
'package.json' does not have a 'main' field.
94+
Entering conditional exports.
95+
Matched 'exports' condition 'types'.
96+
Entering conditional exports.
97+
Saw non-matching condition 'import'.
98+
Matched 'exports' condition 'default'.
99+
Using 'exports' subpath '.' with target './index.d.ts'.
98100
File '/Users/name/projects/web/node_modules/@types/yargs/index.d.ts' exists - use it as a name resolution result.
101+
Resolved under condition 'default'.
102+
Exiting conditional exports.
103+
Resolved under condition 'types'.
104+
Exiting conditional exports.
99105
Resolving real path for '/Users/name/projects/web/node_modules/@types/yargs/index.d.ts', result '/Users/name/projects/web/node_modules/@types/yargs/index.d.ts'.
100106
======== Type reference directive 'yargs' was successfully resolved to '/Users/name/projects/web/node_modules/@types/yargs/index.d.ts' with Package ID 'yargs/index.d.ts@17.0.12', primary: true. ========
101107
File '/a/lib/package.json' does not exist.

0 commit comments

Comments
 (0)