Skip to content

Commit 26f5506

Browse files
committed
Tighten heuristic for definite dts moduleness to check for syntactic default exports
1 parent ca1d19a commit 26f5506

5 files changed

+119
-3
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,8 +1736,9 @@ namespace ts {
17361736
}
17371737
// Declaration files (and ambient modules)
17381738
if (!file || file.isDeclarationFile) {
1739-
// Definitely cannot have a synthetic default if they have a default member specified
1740-
if (resolveExportByName(moduleSymbol, InternalSymbolName.Default, dontResolveAlias)) {
1739+
// Definitely cannot have a synthetic default if they have a syntactic default member specified
1740+
const defaultExportSymbol = resolveExportByName(moduleSymbol, InternalSymbolName.Default, dontResolveAlias);
1741+
if (defaultExportSymbol && defaultExportSymbol.valueDeclaration && isExportAssignment(defaultExportSymbol.valueDeclaration) && !defaultExportSymbol.valueDeclaration.isExportEquals) {
17411742
return false;
17421743
}
17431744
// It _might_ still be incorrect to assume there is no __esModule marker on the import at runtime, even if there is no `default` member
@@ -1777,7 +1778,7 @@ namespace ts {
17771778
if (!exportDefaultSymbol && !hasSyntheticDefault) {
17781779
error(node.name, Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
17791780
}
1780-
else if (!exportDefaultSymbol && hasSyntheticDefault) {
1781+
else if (hasSyntheticDefault) {
17811782
// per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present
17821783
return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
17831784
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//// [tests/cases/compiler/esModuleInteropDefaultMemberMustBeSyntacticallyDefaultExport.ts] ////
2+
3+
//// [point.d.ts]
4+
declare class Point {
5+
x: number;
6+
y: number;
7+
8+
constructor(x: number, y: number);
9+
10+
static default: "foo";
11+
}
12+
13+
export = Point;
14+
//// [index.ts]
15+
import Point from "./point";
16+
17+
const C = Point;
18+
const p = new C(1, 2);
19+
20+
21+
//// [index.js]
22+
"use strict";
23+
var __importDefault = (this && this.__importDefault) || function (mod) {
24+
return (mod && mod.__esModule) ? mod : { "default": mod };
25+
};
26+
exports.__esModule = true;
27+
var point_1 = __importDefault(require("./point"));
28+
var C = point_1["default"];
29+
var p = new C(1, 2);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/compiler/point.d.ts ===
2+
declare class Point {
3+
>Point : Symbol(Point, Decl(point.d.ts, 0, 0))
4+
5+
x: number;
6+
>x : Symbol(Point.x, Decl(point.d.ts, 0, 21))
7+
8+
y: number;
9+
>y : Symbol(Point.y, Decl(point.d.ts, 1, 14))
10+
11+
constructor(x: number, y: number);
12+
>x : Symbol(x, Decl(point.d.ts, 4, 16))
13+
>y : Symbol(y, Decl(point.d.ts, 4, 26))
14+
15+
static default: "foo";
16+
>default : Symbol(Point.default, Decl(point.d.ts, 4, 38))
17+
}
18+
19+
export = Point;
20+
>Point : Symbol(Point, Decl(point.d.ts, 0, 0))
21+
22+
=== tests/cases/compiler/index.ts ===
23+
import Point from "./point";
24+
>Point : Symbol(Point, Decl(index.ts, 0, 6))
25+
26+
const C = Point;
27+
>C : Symbol(C, Decl(index.ts, 2, 5))
28+
>Point : Symbol(Point, Decl(index.ts, 0, 6))
29+
30+
const p = new C(1, 2);
31+
>p : Symbol(p, Decl(index.ts, 3, 5))
32+
>C : Symbol(C, Decl(index.ts, 2, 5))
33+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/point.d.ts ===
2+
declare class Point {
3+
>Point : Point
4+
5+
x: number;
6+
>x : number
7+
8+
y: number;
9+
>y : number
10+
11+
constructor(x: number, y: number);
12+
>x : number
13+
>y : number
14+
15+
static default: "foo";
16+
>default : "foo"
17+
}
18+
19+
export = Point;
20+
>Point : Point
21+
22+
=== tests/cases/compiler/index.ts ===
23+
import Point from "./point";
24+
>Point : typeof Point
25+
26+
const C = Point;
27+
>C : typeof Point
28+
>Point : typeof Point
29+
30+
const p = new C(1, 2);
31+
>p : Point
32+
>new C(1, 2) : Point
33+
>C : typeof Point
34+
>1 : 1
35+
>2 : 2
36+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @esModuleInterop: true
2+
// @filename: point.d.ts
3+
declare class Point {
4+
x: number;
5+
y: number;
6+
7+
constructor(x: number, y: number);
8+
9+
static default: "foo";
10+
}
11+
12+
export = Point;
13+
// @filename: index.ts
14+
import Point from "./point";
15+
16+
const C = Point;
17+
const p = new C(1, 2);

0 commit comments

Comments
 (0)