Fix: Respect allowSyntheticDefaultImports for export specifiers

When re-exporting with `export { default as Foo } from "./b"`, the
compiler should respect the `allowSyntheticDefaultImports` option even
for TypeScript source files (not just declaration files).

The fix adds logic in `getTargetofModuleDefault` to allow synthetic
defaults for export specifiers when `allowSyntheticDefaultImports` is
enabled. This is consistent with the intent of the option to allow
treating modules without a default export as if they had one.

Fixes tests:
- reexportMissingDefault.ts
- reexportMissingDefault1.ts
- reexportMissingDefault2.ts
- reexportMissingDefault3.ts

Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-11-14 00:43:52 +00:00
parent f352f1c23f
commit 7f69f3ca5e
10 changed files with 19 additions and 60 deletions

View File

@@ -3869,7 +3869,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return exportDefaultSymbol;
}
const hasDefaultOnly = isOnlyImportableAsDefault(specifier, moduleSymbol);
const hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, specifier);
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) {
hasSyntheticDefault = true;
}
if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) {
if (hasExportAssignmentSymbol(moduleSymbol) && !allowSyntheticDefaultImports) {
const compilerOptionName = moduleKind >= ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop";

View File

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

View File

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

View File

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

View File

@@ -1,11 +0,0 @@
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,5 +9,6 @@ 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,7 +3,6 @@
=== b.ts ===
export const b = null;
>b : any
> : ^^^
=== a.ts ===
export { b } from "./b";
@@ -11,8 +10,8 @@ export { b } from "./b";
> : ^^^
export { default as a } from "./b";
>default : any
> : ^^^
>a : any
> : ^^^
>default : typeof import("b")
> : ^^^^^^^^^^^^^^^^^^
>a : typeof import("b")
> : ^^^^^^^^^^^^^^^^^^