Skip to content

Commit b24b5c4

Browse files
authored
Allow cross-project references to const enums in isolatedModules when referenced project has preserveConstEnums (#57914)
1 parent fd388f7 commit b24b5c4

File tree

7 files changed

+464
-2
lines changed

7 files changed

+464
-2
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39782,7 +39782,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3978239782
if (getIsolatedModules(compilerOptions)) {
3978339783
Debug.assert(!!(type.symbol.flags & SymbolFlags.ConstEnum));
3978439784
const constEnumDeclaration = type.symbol.valueDeclaration as EnumDeclaration;
39785-
if (constEnumDeclaration.flags & NodeFlags.Ambient && !isValidTypeOnlyAliasUseSite(node)) {
39785+
const redirect = host.getRedirectReferenceForResolutionFromSourceOfProject(getSourceFileOfNode(constEnumDeclaration).resolvedPath);
39786+
if (constEnumDeclaration.flags & NodeFlags.Ambient && !isValidTypeOnlyAliasUseSite(node) && (!redirect || !shouldPreserveConstEnums(redirect.commandLine.options))) {
3978639787
error(node, Diagnostics.Cannot_access_ambient_const_enums_when_0_is_enabled, isolatedModulesLikeFlagName);
3978739788
}
3978839789
}

src/compiler/program.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,6 +1925,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
19251925
getResolvedProjectReferenceByPath,
19261926
forEachResolvedProjectReference,
19271927
isSourceOfProjectReferenceRedirect,
1928+
getRedirectReferenceForResolutionFromSourceOfProject,
19281929
emitBuildInfo,
19291930
fileExists,
19301931
readFile,

src/compiler/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4734,9 +4734,14 @@ export interface Program extends ScriptReferenceHost {
47344734
getProjectReferences(): readonly ProjectReference[] | undefined;
47354735
getResolvedProjectReferences(): readonly (ResolvedProjectReference | undefined)[] | undefined;
47364736
/** @internal */ getProjectReferenceRedirect(fileName: string): string | undefined;
4737-
/** @internal */ getResolvedProjectReferenceToRedirect(fileName: string): ResolvedProjectReference | undefined;
4737+
/**
4738+
* @internal
4739+
* Get the referenced project if the file is input file from that reference project
4740+
*/
4741+
getResolvedProjectReferenceToRedirect(fileName: string): ResolvedProjectReference | undefined;
47384742
/** @internal */ forEachResolvedProjectReference<T>(cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined): T | undefined;
47394743
/** @internal */ getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined;
4744+
/** @internal */ getRedirectReferenceForResolutionFromSourceOfProject(filePath: Path): ResolvedProjectReference | undefined;
47404745
/** @internal */ isSourceOfProjectReferenceRedirect(fileName: string): boolean;
47414746
/** @internal */ getBuildInfo?(): BuildInfo;
47424747
/** @internal */ emitBuildInfo(writeFile?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult;
@@ -4853,6 +4858,7 @@ export interface TypeCheckerHost extends ModuleSpecifierResolutionHost {
48534858
getSourceFile(fileName: string): SourceFile | undefined;
48544859
getProjectReferenceRedirect(fileName: string): string | undefined;
48554860
isSourceOfProjectReferenceRedirect(fileName: string): boolean;
4861+
getRedirectReferenceForResolutionFromSourceOfProject(filePath: Path): ResolvedProjectReference | undefined;
48564862
getModeForUsageLocation(file: SourceFile, usage: StringLiteralLike): ResolutionMode;
48574863

48584864
getResolvedModule(f: SourceFile, moduleName: string, mode: ResolutionMode): ResolvedModuleWithFailedLookupLocations | undefined;

src/testRunner/unittests/tsc/projectReferences.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,31 @@ describe("unittests:: tsc:: projectReferences::", () => {
4949
}),
5050
commandLineArgs: ["--p", "src/project"],
5151
});
52+
53+
verifyTsc({
54+
scenario: "projectReferences",
55+
subScenario: "referencing ambient const enum from referenced project with preserveConstEnums",
56+
fs: () =>
57+
loadProjectFromFiles({
58+
"/src/utils/index.ts": "export const enum E { A = 1 }",
59+
"/src/utils/index.d.ts": "export declare const enum E { A = 1 }",
60+
"/src/utils/tsconfig.json": jsonToReadableText({
61+
compilerOptions: {
62+
composite: true,
63+
declaration: true,
64+
preserveConstEnums: true,
65+
},
66+
}),
67+
"/src/project/index.ts": `import { E } from "../utils"; E.A;`,
68+
"/src/project/tsconfig.json": jsonToReadableText({
69+
compilerOptions: {
70+
isolatedModules: true,
71+
},
72+
references: [
73+
{ path: "../utils" },
74+
],
75+
}),
76+
}),
77+
commandLineArgs: ["--p", "src/project"],
78+
});
5279
});

src/testRunner/unittests/tsserver/projectReferences.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,35 @@ function foo() {
347347
baselineTsserverLogs("projectReferences", "reusing d.ts files from composite and non composite projects", session);
348348
});
349349

350+
it("referencing const enum from referenced project with preserveConstEnums", () => {
351+
const projectLocation = `/user/username/projects/project`;
352+
const utilsIndex: File = {
353+
path: `${projectLocation}/src/utils/index.ts`,
354+
content: "export const enum E { A = 1 }",
355+
};
356+
const utilsDeclaration: File = {
357+
path: `${projectLocation}/src/utils/index.d.ts`,
358+
content: "export declare const enum E { A = 1 }",
359+
};
360+
const utilsConfig: File = {
361+
path: `${projectLocation}/src/utils/tsconfig.json`,
362+
content: jsonToReadableText({ compilerOptions: { composite: true, declaration: true, preserveConstEnums: true } }),
363+
};
364+
const projectIndex: File = {
365+
path: `${projectLocation}/src/project/index.ts`,
366+
content: `import { E } from "../utils"; E.A;`,
367+
};
368+
const projectConfig: File = {
369+
path: `${projectLocation}/src/project/tsconfig.json`,
370+
content: jsonToReadableText({ compilerOptions: { isolatedModules: true }, references: [{ path: "../utils" }] }),
371+
};
372+
const host = createServerHost([libFile, utilsIndex, utilsDeclaration, utilsConfig, projectIndex, projectConfig]);
373+
const session = new TestSession(host);
374+
openFilesForSession([projectIndex], session);
375+
verifyGetErrRequest({ session, files: [projectIndex] });
376+
baselineTsserverLogs("projectReferences", `referencing const enum from referenced project with preserveConstEnums`, session);
377+
});
378+
350379
describe("when references are monorepo like with symlinks", () => {
351380
interface Packages {
352381
bPackageJson: File;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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/project/index.ts]
19+
import { E } from "../utils"; E.A;
20+
21+
//// [/src/project/tsconfig.json]
22+
{
23+
"compilerOptions": {
24+
"isolatedModules": true
25+
},
26+
"references": [
27+
{
28+
"path": "../utils"
29+
}
30+
]
31+
}
32+
33+
//// [/src/utils/index.d.ts]
34+
export declare const enum E { A = 1 }
35+
36+
//// [/src/utils/index.ts]
37+
export const enum E { A = 1 }
38+
39+
//// [/src/utils/tsconfig.json]
40+
{
41+
"compilerOptions": {
42+
"composite": true,
43+
"declaration": true,
44+
"preserveConstEnums": true
45+
}
46+
}
47+
48+
49+
50+
Output::
51+
/lib/tsc --p src/project
52+
exitCode:: ExitStatus.Success
53+
54+
55+
//// [/src/project/index.js]
56+
"use strict";
57+
Object.defineProperty(exports, "__esModule", { value: true });
58+
var utils_1 = require("../utils");
59+
utils_1.E.A;
60+
61+

0 commit comments

Comments
 (0)