Skip to content

Commit 3404817

Browse files
authored
Move ambient const enum error from use site to import in verbatimModuleSyntax (#59438)
1 parent 3568679 commit 3404817

File tree

5 files changed

+198
-1
lines changed

5 files changed

+198
-1
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40710,7 +40710,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4071040710
error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query);
4071140711
}
4071240712

40713-
if (getIsolatedModules(compilerOptions)) {
40713+
// --verbatimModuleSyntax only gets checked here when the enum usage does not
40714+
// resolve to an import, because imports of ambient const enums get checked
40715+
// separately in `checkAliasSymbol`.
40716+
if (
40717+
compilerOptions.isolatedModules
40718+
|| compilerOptions.verbatimModuleSyntax
40719+
&& ok
40720+
&& !resolveName(
40721+
node,
40722+
getFirstIdentifier(node as EntityNameOrEntityNameExpression),
40723+
SymbolFlags.Alias,
40724+
/*nameNotFoundMessage*/ undefined,
40725+
/*isUse*/ false,
40726+
/*excludeGlobals*/ true,
40727+
)
40728+
) {
4071440729
Debug.assert(!!(type.symbol.flags & SymbolFlags.ConstEnum));
4071540730
const constEnumDeclaration = type.symbol.valueDeclaration as EnumDeclaration;
4071640731
const redirect = host.getRedirectReferenceForResolutionFromSourceOfProject(getSourceFileOfNode(constEnumDeclaration).resolvedPath);
@@ -47264,6 +47279,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4726447279
// in files that are unambiguously CommonJS in this mode.
4726547280
error(node, Diagnostics.ESM_syntax_is_not_allowed_in_a_CommonJS_module_when_module_is_set_to_preserve);
4726647281
}
47282+
47283+
if (
47284+
compilerOptions.verbatimModuleSyntax &&
47285+
!isTypeOnlyImportOrExportDeclaration(node) &&
47286+
!(node.flags & NodeFlags.Ambient) &&
47287+
targetFlags & SymbolFlags.ConstEnum
47288+
) {
47289+
const constEnumDeclaration = target.valueDeclaration as EnumDeclaration;
47290+
const redirect = host.getRedirectReferenceForResolutionFromSourceOfProject(getSourceFileOfNode(constEnumDeclaration).resolvedPath);
47291+
if (constEnumDeclaration.flags & NodeFlags.Ambient && (!redirect || !shouldPreserveConstEnums(redirect.commandLine.options))) {
47292+
error(node, Diagnostics.Cannot_access_ambient_const_enums_when_0_is_enabled, isolatedModulesLikeFlagName);
47293+
}
47294+
}
4726747295
}
4726847296

4726947297
if (isImportSpecifier(node)) {

src/testRunner/unittests/tsc/projectReferences.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,42 @@ describe("unittests:: tsc:: projectReferences::", () => {
115115
}),
116116
commandLineArgs: ["--p", "src/project"],
117117
});
118+
119+
verifyTsc({
120+
scenario: "projectReferences",
121+
subScenario: "importing const enum from referenced project with preserveConstEnums and verbatimModuleSyntax",
122+
fs: () =>
123+
loadProjectFromFiles({
124+
"/src/preserve/index.ts": "export const enum E { A = 1 }",
125+
"/src/preserve/index.d.ts": "export declare const enum E { A = 1 }",
126+
"/src/preserve/tsconfig.json": jsonToReadableText({
127+
compilerOptions: {
128+
composite: true,
129+
declaration: true,
130+
preserveConstEnums: true,
131+
},
132+
}),
133+
"/src/no-preserve/index.ts": "export const enum E { A = 1 }",
134+
"/src/no-preserve/index.d.ts": "export declare const enum F { A = 1 }",
135+
"/src/no-preserve/tsconfig.json": jsonToReadableText({
136+
compilerOptions: {
137+
composite: true,
138+
declaration: true,
139+
preserveConstEnums: false,
140+
},
141+
}),
142+
"/src/project/index.ts": `import { E } from "../preserve";\nimport { F } from "../no-preserve";\nE.A; F.A;`,
143+
"/src/project/tsconfig.json": jsonToReadableText({
144+
compilerOptions: {
145+
module: "preserve",
146+
verbatimModuleSyntax: true,
147+
},
148+
references: [
149+
{ path: "../preserve" },
150+
{ path: "../no-preserve" },
151+
],
152+
}),
153+
}),
154+
commandLineArgs: ["--p", "src/project", "--pretty", "false"],
155+
});
118156
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
currentDirectory:: / useCaseSensitiveFileNames: false
2+
Input::
3+
//// [/lib/lib.d.ts]
4+
/// <reference no-default-lib="true"/>
5+
interface Boolean {}
6+
interface Function {}
7+
interface CallableFunction {}
8+
interface NewableFunction {}
9+
interface IArguments {}
10+
interface Number { toExponential: any; }
11+
interface Object {}
12+
interface RegExp {}
13+
interface String { charAt: any; }
14+
interface Array<T> { length: number; [n: number]: T; }
15+
interface ReadonlyArray<T> {}
16+
declare const console: { log(msg: any): void; };
17+
18+
//// [/src/no-preserve/index.d.ts]
19+
export declare const enum F { A = 1 }
20+
21+
//// [/src/no-preserve/index.ts]
22+
export const enum E { A = 1 }
23+
24+
//// [/src/no-preserve/tsconfig.json]
25+
{
26+
"compilerOptions": {
27+
"composite": true,
28+
"declaration": true,
29+
"preserveConstEnums": false
30+
}
31+
}
32+
33+
//// [/src/preserve/index.d.ts]
34+
export declare const enum E { A = 1 }
35+
36+
//// [/src/preserve/index.ts]
37+
export const enum E { A = 1 }
38+
39+
//// [/src/preserve/tsconfig.json]
40+
{
41+
"compilerOptions": {
42+
"composite": true,
43+
"declaration": true,
44+
"preserveConstEnums": true
45+
}
46+
}
47+
48+
//// [/src/project/index.ts]
49+
import { E } from "../preserve";
50+
import { F } from "../no-preserve";
51+
E.A; F.A;
52+
53+
//// [/src/project/tsconfig.json]
54+
{
55+
"compilerOptions": {
56+
"module": "preserve",
57+
"verbatimModuleSyntax": true
58+
},
59+
"references": [
60+
{
61+
"path": "../preserve"
62+
},
63+
{
64+
"path": "../no-preserve"
65+
}
66+
]
67+
}
68+
69+
70+
71+
Output::
72+
/lib/tsc --p src/project --pretty false
73+
src/project/index.ts(2,10): error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
74+
exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated
75+
76+
77+
//// [/src/project/index.js]
78+
import { E } from "../preserve";
79+
import { F } from "../no-preserve";
80+
E.A;
81+
F.A;
82+
83+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/a.ts(1,10): error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
2+
/a.ts(4,1): error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
3+
/b.ts(1,10): error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
4+
5+
6+
==== /node_modules/pkg/index.d.ts (0 errors) ====
7+
export declare const enum E { A, B, C }
8+
declare global {
9+
const enum F { A, B, C }
10+
}
11+
12+
==== /a.ts (2 errors) ====
13+
import { E } from "pkg"; // Error
14+
~
15+
!!! error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
16+
import type { E as _E } from "pkg"; // Ok
17+
console.log(E.A); // Ok
18+
F.A; // Error
19+
~
20+
!!! error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
21+
22+
==== /b.ts (1 errors) ====
23+
export { E } from "pkg"; // Error
24+
~
25+
!!! error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
26+
export type { E as _E } from "pkg"; // Ok
27+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// @verbatimModuleSyntax: true
2+
// @target: esnext
3+
// @module: preserve
4+
// @noEmit: true
5+
// @noTypesAndSymbols: true
6+
7+
// @Filename: /node_modules/pkg/index.d.ts
8+
export declare const enum E { A, B, C }
9+
declare global {
10+
const enum F { A, B, C }
11+
}
12+
13+
// @Filename: /a.ts
14+
import { E } from "pkg"; // Error
15+
import type { E as _E } from "pkg"; // Ok
16+
console.log(E.A); // Ok
17+
F.A; // Error
18+
19+
// @Filename: /b.ts
20+
export { E } from "pkg"; // Error
21+
export type { E as _E } from "pkg"; // Ok

0 commit comments

Comments
 (0)