mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-11 06:02:53 -05:00
Don't create expando object literals in TS (#26525)
Previously, getWidenedTypedFromJSPropertyAssignment was not called for
Typescript code. Since property assignments on functions, it is. That
meant that property assignments would incorrectly create a JS container
for empty object literals in a property assignment, even in Typescript:
```ts
const one = () => 1
one.p = {}
one.p.q = {} // should not work in Typescript!
```
Now empty object literals never create expando objects in Typescript,
because getJSExpandoObjectType requires the declaration to be in a JS
file.
This commit is contained in:
committed by
GitHub
parent
5e8b63cd1d
commit
03653934c3
@@ -4795,7 +4795,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getJSExpandoObjectType(decl: Node, symbol: Symbol, init: Expression | undefined): Type | undefined {
|
||||
if (!init || !isObjectLiteralExpression(init) || init.properties.length) {
|
||||
if (!isInJavaScriptFile(decl) || !init || !isObjectLiteralExpression(init) || init.properties.length) {
|
||||
return undefined;
|
||||
}
|
||||
const exports = createSymbolTable();
|
||||
|
||||
15
tests/baselines/reference/typeFromPropertyAssignment30.js
Normal file
15
tests/baselines/reference/typeFromPropertyAssignment30.js
Normal file
@@ -0,0 +1,15 @@
|
||||
//// [typeFromPropertyAssignment30.ts]
|
||||
interface Combo {
|
||||
(): number;
|
||||
p?: { [s: string]: number };
|
||||
}
|
||||
const c: Combo = () => 1
|
||||
// should not be an expando object, but contextually typed by Combo.p
|
||||
c.p = {}
|
||||
|
||||
|
||||
|
||||
//// [typeFromPropertyAssignment30.js]
|
||||
var c = function () { return 1; };
|
||||
// should not be an expando object, but contextually typed by Combo.p
|
||||
c.p = {};
|
||||
@@ -0,0 +1,20 @@
|
||||
=== tests/cases/conformance/salsa/typeFromPropertyAssignment30.ts ===
|
||||
interface Combo {
|
||||
>Combo : Symbol(Combo, Decl(typeFromPropertyAssignment30.ts, 0, 0))
|
||||
|
||||
(): number;
|
||||
p?: { [s: string]: number };
|
||||
>p : Symbol(Combo.p, Decl(typeFromPropertyAssignment30.ts, 1, 15))
|
||||
>s : Symbol(s, Decl(typeFromPropertyAssignment30.ts, 2, 11))
|
||||
}
|
||||
const c: Combo = () => 1
|
||||
>c : Symbol(c, Decl(typeFromPropertyAssignment30.ts, 4, 5), Decl(typeFromPropertyAssignment30.ts, 4, 24))
|
||||
>Combo : Symbol(Combo, Decl(typeFromPropertyAssignment30.ts, 0, 0))
|
||||
|
||||
// should not be an expando object, but contextually typed by Combo.p
|
||||
c.p = {}
|
||||
>c.p : Symbol(Combo.p, Decl(typeFromPropertyAssignment30.ts, 1, 15))
|
||||
>c : Symbol(c, Decl(typeFromPropertyAssignment30.ts, 4, 5), Decl(typeFromPropertyAssignment30.ts, 4, 24))
|
||||
>p : Symbol(Combo.p, Decl(typeFromPropertyAssignment30.ts, 1, 15))
|
||||
|
||||
|
||||
21
tests/baselines/reference/typeFromPropertyAssignment30.types
Normal file
21
tests/baselines/reference/typeFromPropertyAssignment30.types
Normal file
@@ -0,0 +1,21 @@
|
||||
=== tests/cases/conformance/salsa/typeFromPropertyAssignment30.ts ===
|
||||
interface Combo {
|
||||
(): number;
|
||||
p?: { [s: string]: number };
|
||||
>p : { [s: string]: number; }
|
||||
>s : string
|
||||
}
|
||||
const c: Combo = () => 1
|
||||
>c : Combo
|
||||
>() => 1 : { (): number; p: {}; }
|
||||
>1 : 1
|
||||
|
||||
// should not be an expando object, but contextually typed by Combo.p
|
||||
c.p = {}
|
||||
>c.p = {} : {}
|
||||
>c.p : { [s: string]: number; }
|
||||
>c : Combo
|
||||
>p : { [s: string]: number; }
|
||||
>{} : {}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
interface Combo {
|
||||
(): number;
|
||||
p?: { [s: string]: number };
|
||||
}
|
||||
const c: Combo = () => 1
|
||||
// should not be an expando object, but contextually typed by Combo.p
|
||||
c.p = {}
|
||||
|
||||
Reference in New Issue
Block a user