Move ambient const enum error from use site to import in verbatimModuleSyntax (#59438)

This commit is contained in:
Andrew Branch 2024-07-30 11:20:59 -07:00 коммит произвёл GitHub
Родитель 356867908c
Коммит 34048178a2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 198 добавлений и 1 удалений

Просмотреть файл

@ -40710,7 +40710,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
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);
}
if (getIsolatedModules(compilerOptions)) {
// --verbatimModuleSyntax only gets checked here when the enum usage does not
// resolve to an import, because imports of ambient const enums get checked
// separately in `checkAliasSymbol`.
if (
compilerOptions.isolatedModules
|| compilerOptions.verbatimModuleSyntax
&& ok
&& !resolveName(
node,
getFirstIdentifier(node as EntityNameOrEntityNameExpression),
SymbolFlags.Alias,
/*nameNotFoundMessage*/ undefined,
/*isUse*/ false,
/*excludeGlobals*/ true,
)
) {
Debug.assert(!!(type.symbol.flags & SymbolFlags.ConstEnum));
const constEnumDeclaration = type.symbol.valueDeclaration as EnumDeclaration;
const redirect = host.getRedirectReferenceForResolutionFromSourceOfProject(getSourceFileOfNode(constEnumDeclaration).resolvedPath);
@ -47264,6 +47279,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// in files that are unambiguously CommonJS in this mode.
error(node, Diagnostics.ESM_syntax_is_not_allowed_in_a_CommonJS_module_when_module_is_set_to_preserve);
}
if (
compilerOptions.verbatimModuleSyntax &&
!isTypeOnlyImportOrExportDeclaration(node) &&
!(node.flags & NodeFlags.Ambient) &&
targetFlags & SymbolFlags.ConstEnum
) {
const constEnumDeclaration = target.valueDeclaration as EnumDeclaration;
const redirect = host.getRedirectReferenceForResolutionFromSourceOfProject(getSourceFileOfNode(constEnumDeclaration).resolvedPath);
if (constEnumDeclaration.flags & NodeFlags.Ambient && (!redirect || !shouldPreserveConstEnums(redirect.commandLine.options))) {
error(node, Diagnostics.Cannot_access_ambient_const_enums_when_0_is_enabled, isolatedModulesLikeFlagName);
}
}
}
if (isImportSpecifier(node)) {

Просмотреть файл

@ -115,4 +115,42 @@ describe("unittests:: tsc:: projectReferences::", () => {
}),
commandLineArgs: ["--p", "src/project"],
});
verifyTsc({
scenario: "projectReferences",
subScenario: "importing const enum from referenced project with preserveConstEnums and verbatimModuleSyntax",
fs: () =>
loadProjectFromFiles({
"/src/preserve/index.ts": "export const enum E { A = 1 }",
"/src/preserve/index.d.ts": "export declare const enum E { A = 1 }",
"/src/preserve/tsconfig.json": jsonToReadableText({
compilerOptions: {
composite: true,
declaration: true,
preserveConstEnums: true,
},
}),
"/src/no-preserve/index.ts": "export const enum E { A = 1 }",
"/src/no-preserve/index.d.ts": "export declare const enum F { A = 1 }",
"/src/no-preserve/tsconfig.json": jsonToReadableText({
compilerOptions: {
composite: true,
declaration: true,
preserveConstEnums: false,
},
}),
"/src/project/index.ts": `import { E } from "../preserve";\nimport { F } from "../no-preserve";\nE.A; F.A;`,
"/src/project/tsconfig.json": jsonToReadableText({
compilerOptions: {
module: "preserve",
verbatimModuleSyntax: true,
},
references: [
{ path: "../preserve" },
{ path: "../no-preserve" },
],
}),
}),
commandLineArgs: ["--p", "src/project", "--pretty", "false"],
});
});

Просмотреть файл

@ -0,0 +1,83 @@
currentDirectory:: / useCaseSensitiveFileNames: false
Input::
//// [/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };
//// [/src/no-preserve/index.d.ts]
export declare const enum F { A = 1 }
//// [/src/no-preserve/index.ts]
export const enum E { A = 1 }
//// [/src/no-preserve/tsconfig.json]
{
"compilerOptions": {
"composite": true,
"declaration": true,
"preserveConstEnums": false
}
}
//// [/src/preserve/index.d.ts]
export declare const enum E { A = 1 }
//// [/src/preserve/index.ts]
export const enum E { A = 1 }
//// [/src/preserve/tsconfig.json]
{
"compilerOptions": {
"composite": true,
"declaration": true,
"preserveConstEnums": true
}
}
//// [/src/project/index.ts]
import { E } from "../preserve";
import { F } from "../no-preserve";
E.A; F.A;
//// [/src/project/tsconfig.json]
{
"compilerOptions": {
"module": "preserve",
"verbatimModuleSyntax": true
},
"references": [
{
"path": "../preserve"
},
{
"path": "../no-preserve"
}
]
}
Output::
/lib/tsc --p src/project --pretty false
src/project/index.ts(2,10): error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated
//// [/src/project/index.js]
import { E } from "../preserve";
import { F } from "../no-preserve";
E.A;
F.A;

Просмотреть файл

@ -0,0 +1,27 @@
/a.ts(1,10): error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
/a.ts(4,1): error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
/b.ts(1,10): error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
==== /node_modules/pkg/index.d.ts (0 errors) ====
export declare const enum E { A, B, C }
declare global {
const enum F { A, B, C }
}
==== /a.ts (2 errors) ====
import { E } from "pkg"; // Error
~
!!! error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
import type { E as _E } from "pkg"; // Ok
console.log(E.A); // Ok
F.A; // Error
~
!!! error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
==== /b.ts (1 errors) ====
export { E } from "pkg"; // Error
~
!!! error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled.
export type { E as _E } from "pkg"; // Ok

Просмотреть файл

@ -0,0 +1,21 @@
// @verbatimModuleSyntax: true
// @target: esnext
// @module: preserve
// @noEmit: true
// @noTypesAndSymbols: true
// @Filename: /node_modules/pkg/index.d.ts
export declare const enum E { A, B, C }
declare global {
const enum F { A, B, C }
}
// @Filename: /a.ts
import { E } from "pkg"; // Error
import type { E as _E } from "pkg"; // Ok
console.log(E.A); // Ok
F.A; // Error
// @Filename: /b.ts
export { E } from "pkg"; // Error
export type { E as _E } from "pkg"; // Ok