Fix: Only allow synthetic defaults for declaration files in export specifiers

Corrected the fix to only allow synthetic defaults when re-exporting
from declaration files (not TypeScript source files). This aligns with
the issue description which states that declaration files may correspond
to CommonJS modules at runtime where a default import can reference the
whole module.exports symbol.

Only tests targeting .d.ts files should pass without errors:
- reexportMissingDefault4.ts (targets b.d.ts) ✓
- reexportMissingDefault5.ts (targets b.d.ts) ✓

Tests targeting .ts files correctly maintain their errors:
- reexportMissingDefault.ts, 1, 2, 3, 6, 7 (all target b.ts)

Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-11-14 01:06:49 +00:00
parent 7f69f3ca5e
commit d85f072ddd
10 changed files with 63 additions and 16 deletions

View File

@@ -3870,11 +3870,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
const hasDefaultOnly = isOnlyImportableAsDefault(specifier, moduleSymbol);
let hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, specifier);
// For export specifiers re-exporting 'default', when allowSyntheticDefaultImports is enabled,
// allow synthetic default even from TypeScript source files (not just declaration files).
// This is consistent with the intent of allowSyntheticDefaultImports to allow treating modules
// without a default export as if they had one.
if (!hasSyntheticDefault && isExportSpecifier(node) && allowSyntheticDefaultImports) {
// For export specifiers re-exporting 'default' from declaration files, when allowSyntheticDefaultImports
// is enabled, allow synthetic default. Declaration files may correspond to CommonJS modules at runtime,
// where a default import is allowed to reference the whole module.exports symbol.
if (!hasSyntheticDefault && isExportSpecifier(node) && allowSyntheticDefaultImports && (!file || file.isDeclarationFile)) {
hasSyntheticDefault = true;
}
if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) {

View File

@@ -0,0 +1,11 @@
a.ts(2,10): error TS2305: Module '"./b"' has no exported member 'default'.
==== b.ts (0 errors) ====
export const b = null;
==== a.ts (1 errors) ====
export { b } from "./b";
export { default } from "./b";
~~~~~~~
!!! error TS2305: Module '"./b"' has no exported member 'default'.

View File

@@ -3,6 +3,7 @@
=== b.ts ===
export const b = null;
>b : any
> : ^^^
=== a.ts ===
export { b } from "./b";
@@ -10,6 +11,6 @@ export { b } from "./b";
> : ^^^
export { default } from "./b";
>default : typeof import("b")
> : ^^^^^^^^^^^^^^^^^^
>default : any
> : ^^^

View File

@@ -0,0 +1,12 @@
a.ts(2,10): error TS2305: Module '"./b"' has no exported member 'default'.
==== b.ts (0 errors) ====
export const b = null;
==== a.ts (1 errors) ====
export { b } from "./b";
export { default } from "./b";
~~~~~~~
!!! error TS2305: Module '"./b"' has no exported member 'default'.

View File

@@ -3,6 +3,7 @@
=== b.ts ===
export const b = null;
>b : any
> : ^^^
=== a.ts ===
export { b } from "./b";
@@ -10,6 +11,6 @@ export { b } from "./b";
> : ^^^
export { default } from "./b";
>default : typeof import("b")
> : ^^^^^^^^^^^^^^^^^^
>default : any
> : ^^^

View File

@@ -0,0 +1,11 @@
a.ts(2,10): error TS2305: Module '"./b"' has no exported member 'default'.
==== b.ts (0 errors) ====
export const b = null;
==== a.ts (1 errors) ====
export { b } from "./b";
export { default } from "./b";
~~~~~~~
!!! error TS2305: Module '"./b"' has no exported member 'default'.

View File

@@ -3,6 +3,7 @@
=== b.ts ===
export const b = null;
>b : any
> : ^^^
=== a.ts ===
export { b } from "./b";
@@ -10,6 +11,6 @@ export { b } from "./b";
> : ^^^
export { default } from "./b";
>default : typeof import("b")
> : ^^^^^^^^^^^^^^^^^^
>default : any
> : ^^^

View File

@@ -0,0 +1,11 @@
a.ts(2,10): error TS2305: Module '"./b"' has no exported member 'default'.
==== b.ts (0 errors) ====
export const b = null;
==== a.ts (1 errors) ====
export { b } from "./b";
export { default as a } from "./b";
~~~~~~~
!!! error TS2305: Module '"./b"' has no exported member 'default'.

View File

@@ -9,6 +9,5 @@ export { b } from "./b";
>b : Symbol(b, Decl(a.ts, 0, 8))
export { default as a } from "./b";
>default : Symbol("b", Decl(b.ts, 0, 0))
>a : Symbol(a, Decl(a.ts, 1, 8))

View File

@@ -3,6 +3,7 @@
=== b.ts ===
export const b = null;
>b : any
> : ^^^
=== a.ts ===
export { b } from "./b";
@@ -10,8 +11,8 @@ export { b } from "./b";
> : ^^^
export { default as a } from "./b";
>default : typeof import("b")
> : ^^^^^^^^^^^^^^^^^^
>a : typeof import("b")
> : ^^^^^^^^^^^^^^^^^^
>default : any
> : ^^^
>a : any
> : ^^^