Skip to content

Commit 10edf6f

Browse files
authored
Widen export assignment types so they arent accidentally fresh (microsoft#27397)
1 parent 04266aa commit 10edf6f

6 files changed

+177
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5180,7 +5180,7 @@ namespace ts {
51805180
return type;
51815181
}
51825182
if (declaration.kind === SyntaxKind.ExportAssignment) {
5183-
return checkExpression((<ExportAssignment>declaration).expression);
5183+
return widenTypeForVariableLikeDeclaration(checkExpressionCached((<ExportAssignment>declaration).expression), declaration);
51845184
}
51855185

51865186
// Handle variable, parameter or property
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
tests/cases/compiler/index.ts(10,6): error TS2345: Argument of type '{ foob: string; }' is not assignable to parameter of type 'IFoo'.
2+
Property 'foo' is missing in type '{ foob: string; }'.
3+
tests/cases/compiler/index.ts(12,6): error TS2345: Argument of type '{ foob: string; }' is not assignable to parameter of type 'IFoo'.
4+
Property 'foo' is missing in type '{ foob: string; }'.
5+
6+
7+
==== tests/cases/compiler/items.ts (0 errors) ====
8+
export default {
9+
foob: "a"
10+
}
11+
12+
export const q = {
13+
foob: "b"
14+
}
15+
==== tests/cases/compiler/index.ts (2 errors) ====
16+
import B, {q} from "./items";
17+
18+
interface IFoo {
19+
foo: string;
20+
}
21+
22+
function nFoo(x: IFoo) {}
23+
24+
25+
nFoo(q); // for comparison
26+
~
27+
!!! error TS2345: Argument of type '{ foob: string; }' is not assignable to parameter of type 'IFoo'.
28+
!!! error TS2345: Property 'foo' is missing in type '{ foob: string; }'.
29+
30+
nFoo(B);
31+
~
32+
!!! error TS2345: Argument of type '{ foob: string; }' is not assignable to parameter of type 'IFoo'.
33+
!!! error TS2345: Property 'foo' is missing in type '{ foob: string; }'.
34+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//// [tests/cases/compiler/exportDefaultStripsFreshness.ts] ////
2+
3+
//// [items.ts]
4+
export default {
5+
foob: "a"
6+
}
7+
8+
export const q = {
9+
foob: "b"
10+
}
11+
//// [index.ts]
12+
import B, {q} from "./items";
13+
14+
interface IFoo {
15+
foo: string;
16+
}
17+
18+
function nFoo(x: IFoo) {}
19+
20+
21+
nFoo(q); // for comparison
22+
23+
nFoo(B);
24+
25+
26+
//// [items.js]
27+
"use strict";
28+
exports.__esModule = true;
29+
exports["default"] = {
30+
foob: "a"
31+
};
32+
exports.q = {
33+
foob: "b"
34+
};
35+
//// [index.js]
36+
"use strict";
37+
exports.__esModule = true;
38+
var items_1 = require("./items");
39+
function nFoo(x) { }
40+
nFoo(items_1.q); // for comparison
41+
nFoo(items_1["default"]);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
=== tests/cases/compiler/items.ts ===
2+
export default {
3+
foob: "a"
4+
>foob : Symbol(foob, Decl(items.ts, 0, 16))
5+
}
6+
7+
export const q = {
8+
>q : Symbol(q, Decl(items.ts, 4, 12))
9+
10+
foob: "b"
11+
>foob : Symbol(foob, Decl(items.ts, 4, 18))
12+
}
13+
=== tests/cases/compiler/index.ts ===
14+
import B, {q} from "./items";
15+
>B : Symbol(B, Decl(index.ts, 0, 6))
16+
>q : Symbol(q, Decl(index.ts, 0, 11))
17+
18+
interface IFoo {
19+
>IFoo : Symbol(IFoo, Decl(index.ts, 0, 29))
20+
21+
foo: string;
22+
>foo : Symbol(IFoo.foo, Decl(index.ts, 2, 16))
23+
}
24+
25+
function nFoo(x: IFoo) {}
26+
>nFoo : Symbol(nFoo, Decl(index.ts, 4, 1))
27+
>x : Symbol(x, Decl(index.ts, 6, 14))
28+
>IFoo : Symbol(IFoo, Decl(index.ts, 0, 29))
29+
30+
31+
nFoo(q); // for comparison
32+
>nFoo : Symbol(nFoo, Decl(index.ts, 4, 1))
33+
>q : Symbol(q, Decl(index.ts, 0, 11))
34+
35+
nFoo(B);
36+
>nFoo : Symbol(nFoo, Decl(index.ts, 4, 1))
37+
>B : Symbol(B, Decl(index.ts, 0, 6))
38+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
=== tests/cases/compiler/items.ts ===
2+
export default {
3+
>{ foob: "a"} : { foob: string; }
4+
5+
foob: "a"
6+
>foob : string
7+
>"a" : "a"
8+
}
9+
10+
export const q = {
11+
>q : { foob: string; }
12+
>{ foob: "b"} : { foob: string; }
13+
14+
foob: "b"
15+
>foob : string
16+
>"b" : "b"
17+
}
18+
=== tests/cases/compiler/index.ts ===
19+
import B, {q} from "./items";
20+
>B : { foob: string; }
21+
>q : { foob: string; }
22+
23+
interface IFoo {
24+
foo: string;
25+
>foo : string
26+
}
27+
28+
function nFoo(x: IFoo) {}
29+
>nFoo : (x: IFoo) => void
30+
>x : IFoo
31+
32+
33+
nFoo(q); // for comparison
34+
>nFoo(q) : void
35+
>nFoo : (x: IFoo) => void
36+
>q : { foob: string; }
37+
38+
nFoo(B);
39+
>nFoo(B) : void
40+
>nFoo : (x: IFoo) => void
41+
>B : { foob: string; }
42+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// @filename: items.ts
2+
export default {
3+
foob: "a"
4+
}
5+
6+
export const q = {
7+
foob: "b"
8+
}
9+
// @filename: index.ts
10+
import B, {q} from "./items";
11+
12+
interface IFoo {
13+
foo: string;
14+
}
15+
16+
function nFoo(x: IFoo) {}
17+
18+
19+
nFoo(q); // for comparison
20+
21+
nFoo(B);

0 commit comments

Comments
 (0)