Skip to content

Commit d90eb0d

Browse files
authored
Require module/moduleResolution to match when either is node16/nodenext (#54567)
1 parent 49deff2 commit d90eb0d

File tree

36 files changed

+650
-750
lines changed

36 files changed

+650
-750
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4329,6 +4329,14 @@
43294329
"category": "Error",
43304330
"code": 5108
43314331
},
4332+
"Option 'moduleResolution' must be set to '{0}' (or left unspecified) when option 'module' is set to '{1}'.": {
4333+
"category": "Error",
4334+
"code": 5109
4335+
},
4336+
"Option 'module' must be set to '{0}' when option 'moduleResolution' is set to '{1}'.": {
4337+
"category": "Error",
4338+
"code": 5110
4339+
},
43324340

43334341
"Generates a sourcemap for each corresponding '.d.ts' file.": {
43344342
"category": "Message",

src/compiler/program.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4404,6 +4404,24 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
44044404
createOptionValueDiagnostic("moduleResolution", Diagnostics.Option_0_can_only_be_used_when_module_is_set_to_es2015_or_later, "bundler");
44054405
}
44064406

4407+
if (
4408+
ModuleKind[moduleKind] &&
4409+
(ModuleKind.Node16 <= moduleKind && moduleKind <= ModuleKind.NodeNext) &&
4410+
!(ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext)
4411+
) {
4412+
const moduleKindName = ModuleKind[moduleKind];
4413+
createOptionValueDiagnostic("moduleResolution", Diagnostics.Option_moduleResolution_must_be_set_to_0_or_left_unspecified_when_option_module_is_set_to_1, moduleKindName, moduleKindName);
4414+
}
4415+
else if (
4416+
ModuleResolutionKind[moduleResolution] &&
4417+
(ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext) &&
4418+
!(ModuleKind.Node16 <= moduleKind && moduleKind <= ModuleKind.NodeNext)
4419+
) {
4420+
const moduleResolutionName = ModuleResolutionKind[moduleResolution];
4421+
createOptionValueDiagnostic("module", Diagnostics.Option_module_must_be_set_to_0_when_option_moduleResolution_is_set_to_1, moduleResolutionName, moduleResolutionName);
4422+
}
4423+
4424+
44074425
// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
44084426
if (!options.noEmit && !options.suppressOutputPathCheck) {
44094427
const emitHost = getEmitHost();

tests/baselines/reference/allowImportingTsExtensions(moduleresolution=node16).errors.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
error TS5110: Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'.
12
/c.ts(1,16): error TS2307: Cannot find module './thisfiledoesnotexist.ts' or its corresponding type declarations.
23

34

5+
!!! error TS5110: Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'.
46
==== /ts.ts (0 errors) ====
57
export {};
68

tests/baselines/reference/allowImportingTsExtensions(moduleresolution=nodenext).errors.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
12
/c.ts(1,16): error TS2307: Cannot find module './thisfiledoesnotexist.ts' or its corresponding type declarations.
23

34

5+
!!! error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
46
==== /ts.ts (0 errors) ====
57
export {};
68

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error TS5110: Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'.
2+
3+
4+
!!! error TS5110: Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'.
5+
==== /types.d.ts (0 errors) ====
6+
export declare type User = {
7+
name: string;
8+
}
9+
10+
==== /a.ts (0 errors) ====
11+
import type { User } from "./types.d.ts";
12+
export type { User } from "./types.d.ts";
13+
14+
export const user: User = { name: "John" };
15+
16+
export function getUser(): import("./types.d.ts").User {
17+
return user;
18+
}
19+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
2+
3+
4+
!!! error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
5+
==== /types.d.ts (0 errors) ====
6+
export declare type User = {
7+
name: string;
8+
}
9+
10+
==== /a.ts (0 errors) ====
11+
import type { User } from "./types.d.ts";
12+
export type { User } from "./types.d.ts";
13+
14+
export const user: User = { name: "John" };
15+
16+
export function getUser(): import("./types.d.ts").User {
17+
return user;
18+
}
19+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error TS5110: Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'.
2+
3+
4+
!!! error TS5110: Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'.
5+
==== /types.d.ts (0 errors) ====
6+
export declare type User = {
7+
name: string;
8+
}
9+
10+
==== /a.ts (0 errors) ====
11+
import type { User } from "./types.d.ts";
12+
export type { User } from "./types.d.ts";
13+
14+
export const user: User = { name: "John" };
15+
16+
export function getUser(): import("./types.d.ts").User {
17+
return user;
18+
}
19+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
2+
3+
4+
!!! error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
5+
==== /types.d.ts (0 errors) ====
6+
export declare type User = {
7+
name: string;
8+
}
9+
10+
==== /a.ts (0 errors) ====
11+
import type { User } from "./types.d.ts";
12+
export type { User } from "./types.d.ts";
13+
14+
export const user: User = { name: "John" };
15+
16+
export function getUser(): import("./types.d.ts").User {
17+
return user;
18+
}
19+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error TS5110: Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'.
2+
3+
4+
!!! error TS5110: Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'.
5+
==== /node_modules/dep/package.json (0 errors) ====
6+
// This documents bug https://github.com/microsoft/TypeScript/issues/50762.
7+
8+
{
9+
"name": "dep",
10+
"version": "1.0.0",
11+
"exports": {
12+
".": {
13+
"import": "./dist/index.mjs",
14+
"require": "./dist/index.js",
15+
"types": "./dist/index.d.ts",
16+
}
17+
}
18+
}
19+
20+
==== /node_modules/dep/dist/index.d.ts (0 errors) ====
21+
export {};
22+
23+
==== /node_modules/dep/dist/index.mjs (0 errors) ====
24+
export {};
25+
26+
==== /index.mts (0 errors) ====
27+
import {} from "dep";
28+
// Should be an untyped resolution to dep/dist/index.mjs,
29+
// but the first search is only for TS files, and when
30+
// there's no dist/index.d.mts, it continues looking for
31+
// matching conditions and resolves via `types`.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
2+
3+
4+
!!! error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
5+
==== /node_modules/dep/package.json (0 errors) ====
6+
// This documents bug https://github.com/microsoft/TypeScript/issues/50762.
7+
8+
{
9+
"name": "dep",
10+
"version": "1.0.0",
11+
"exports": {
12+
".": {
13+
"import": "./dist/index.mjs",
14+
"require": "./dist/index.js",
15+
"types": "./dist/index.d.ts",
16+
}
17+
}
18+
}
19+
20+
==== /node_modules/dep/dist/index.d.ts (0 errors) ====
21+
export {};
22+
23+
==== /node_modules/dep/dist/index.mjs (0 errors) ====
24+
export {};
25+
26+
==== /index.mts (0 errors) ====
27+
import {} from "dep";
28+
// Should be an untyped resolution to dep/dist/index.mjs,
29+
// but the first search is only for TS files, and when
30+
// there's no dist/index.d.mts, it continues looking for
31+
// matching conditions and resolves via `types`.

0 commit comments

Comments
 (0)