Skip to content
Open
15 changes: 15 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3794,6 +3794,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// are ESM, there cannot be a synthetic default.
return false;
}
// For other files (not node16/nodenext with impliedNodeFormat), check if we can determine
// the module format from project references
if (!targetMode && file.isDeclarationFile) {
// Try to get the project reference - try both source file mapping and output file mapping
// since declaration files can be mapped either way depending on how they're resolved
const redirect = host.getRedirectFromSourceFile(file.path) || host.getRedirectFromOutput(file.path);
if (redirect) {
// This is a declaration file from a project reference, so we can determine
// its module format from the referenced project's options
const targetModuleKind = host.getEmitModuleFormatOfFile(file);
if (usageMode === ModuleKind.ESNext && ModuleKind.ES2015 <= targetModuleKind && targetModuleKind <= ModuleKind.ESNext) {
return false;
}
}
}
}
if (!allowSyntheticDefaultImports) {
return false;
Expand Down
29 changes: 29 additions & 0 deletions src/testRunner/unittests/tsc/projectReferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,35 @@ describe("unittests:: tsc:: projectReferences::", () => {
commandLineArgs: ["--p", "app", "--pretty", "false"],
});

verifyTsc({
scenario: "projectReferences",
subScenario: "referenced project with esnext module disallows synthetic default imports",
sys: () =>
TestServerHost.createWatchedSystem({
"/home/src/workspaces/project/lib/tsconfig.json": jsonToReadableText({
compilerOptions: {
composite: true,
declaration: true,
module: "esnext",
moduleResolution: "bundler",
},
}),
"/home/src/workspaces/project/lib/utils.ts": "export const test = () => 'test';",
"/home/src/workspaces/project/lib/utils.d.ts": "export declare const test: () => string;",
"/home/src/workspaces/project/app/tsconfig.json": jsonToReadableText({
compilerOptions: {
module: "esnext",
moduleResolution: "bundler",
},
references: [
{ path: "../lib" },
],
}),
"/home/src/workspaces/project/app/index.ts": `import Test from '../lib/utils';\nconsole.log(Test.test());`,
}),
commandLineArgs: ["--p", "app", "--pretty", "false"],
});

verifyTsc({
scenario: "projectReferences",
subScenario: "referencing ambient const enum from referenced project with preserveConstEnums",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ declare const console: { log(msg: any): void; };
Output::
app/src/index.ts(2,28): error TS2613: Module '"/home/src/workspaces/project/app/src/local"' has no default export. Did you mean to use 'import { local } from "/home/src/workspaces/project/app/src/local"' instead?
app/src/index.ts(3,28): error TS2613: Module '"/home/src/workspaces/project/node_modules/esm-package/index"' has no default export. Did you mean to use 'import { esm } from "/home/src/workspaces/project/node_modules/esm-package/index"' instead?
app/src/index.ts(4,28): error TS1192: Module '"/home/src/workspaces/project/lib/dist/a"' has no default export.
app/src/index.ts(5,28): error TS1192: Module '"/home/src/workspaces/project/lib/dist/a"' has no default export.


//// [/home/src/workspaces/project/app/dist/local.js]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
currentDirectory:: /home/src/workspaces/project useCaseSensitiveFileNames:: false
Input::
//// [/home/src/workspaces/project/lib/tsconfig.json]
{
"compilerOptions": {
"composite": true,
"declaration": true,
"module": "esnext",
"moduleResolution": "bundler"
}
}

//// [/home/src/workspaces/project/lib/utils.ts]
export const test = () => 'test';

//// [/home/src/workspaces/project/lib/utils.d.ts]
export declare const test: () => string;

//// [/home/src/workspaces/project/app/tsconfig.json]
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler"
},
"references": [
{
"path": "../lib"
}
]
}

//// [/home/src/workspaces/project/app/index.ts]
import Test from '../lib/utils';
console.log(Test.test());

//// [/home/src/tslibs/TS/Lib/lib.d.ts]
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; };


/home/src/tslibs/TS/Lib/tsc.js --p app --pretty false
Output::
app/index.ts(1,8): error TS1192: Module '"/home/src/workspaces/project/lib/utils"' has no default export.


//// [/home/src/workspaces/project/app/index.js]
import Test from '../lib/utils';
console.log(Test.test());



exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated