mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Fix circularity error when extending class in same JSContainer (#24710)
Do this by not widening properties of an object literal that are 1. JS initialisers 2. and not an object literal These properties have types that will never widen, so the compiler shouldn't ask for the types earlier than it strictly needs to.
This commit is contained in:
parent
0db52da564
commit
d6250c8342
@ -12170,6 +12170,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getWidenedProperty(prop: Symbol, context: WideningContext | undefined): Symbol {
|
||||
if (!(prop.flags & SymbolFlags.Property)) {
|
||||
// Since get accessors already widen their return value there is no need to
|
||||
// widen accessor based properties here.
|
||||
return prop;
|
||||
}
|
||||
if (prop.flags & SymbolFlags.JSContainer) {
|
||||
const node = prop.declarations && first(prop.declarations);
|
||||
const init = getAssignedJavascriptInitializer(node);
|
||||
if (init && init.kind !== SyntaxKind.ObjectLiteralExpression) {
|
||||
// for JS special declarations, the only kind of initializer that will widen is object literals
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
const original = getTypeOfSymbol(prop);
|
||||
const propContext = context && createWideningContext(context, prop.escapedName, /*siblings*/ undefined);
|
||||
const widened = getWidenedTypeWithContext(original, propContext);
|
||||
@ -12190,9 +12203,7 @@ namespace ts {
|
||||
function getWidenedTypeOfObjectLiteral(type: Type, context: WideningContext | undefined): Type {
|
||||
const members = createSymbolTable();
|
||||
for (const prop of getPropertiesOfObjectType(type)) {
|
||||
// Since get accessors already widen their return value there is no need to
|
||||
// widen accessor based properties here.
|
||||
members.set(prop.escapedName, prop.flags & SymbolFlags.Property ? getWidenedProperty(prop, context) : prop);
|
||||
members.set(prop.escapedName, getWidenedProperty(prop, context));
|
||||
}
|
||||
if (context) {
|
||||
for (const prop of getPropertiesOfContext(context)) {
|
||||
@ -15984,10 +15995,10 @@ namespace ts {
|
||||
const decl = getDeclarationOfJSInitializer(node);
|
||||
if (decl) {
|
||||
// a JS object literal whose declaration's symbol has exports is a JS namespace
|
||||
const symbol = getMergedSymbol(decl.symbol);
|
||||
const symbol = getSymbolOfNode(decl);
|
||||
if (symbol && hasEntries(symbol.exports)) {
|
||||
propertiesTable = symbol.exports;
|
||||
symbol.exports.forEach(symbol => propertiesArray.push(getMergedSymbol(symbol)));
|
||||
symbol.exports.forEach(s => propertiesArray.push(getMergedSymbol(s)));
|
||||
return createObjectLiteralType();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
=== tests/cases/conformance/salsa/bug24703.js ===
|
||||
var Common = {};
|
||||
>Common : Symbol(Common, Decl(bug24703.js, 0, 3), Decl(bug24703.js, 0, 16))
|
||||
|
||||
Common.I = class {
|
||||
>Common.I : Symbol(Common.I, Decl(bug24703.js, 0, 16))
|
||||
>Common : Symbol(Common, Decl(bug24703.js, 0, 3), Decl(bug24703.js, 0, 16))
|
||||
>I : Symbol(Common.I, Decl(bug24703.js, 0, 16))
|
||||
|
||||
constructor() {
|
||||
this.i = 1
|
||||
>this.i : Symbol(I.i, Decl(bug24703.js, 2, 19))
|
||||
>this : Symbol(I, Decl(bug24703.js, 1, 10))
|
||||
>i : Symbol(I.i, Decl(bug24703.js, 2, 19))
|
||||
}
|
||||
}
|
||||
Common.O = class extends Common.I {
|
||||
>Common.O : Symbol(Common.O, Decl(bug24703.js, 5, 1))
|
||||
>Common : Symbol(Common, Decl(bug24703.js, 0, 3), Decl(bug24703.js, 0, 16))
|
||||
>O : Symbol(Common.O, Decl(bug24703.js, 5, 1))
|
||||
>Common.I : Symbol(Common.I, Decl(bug24703.js, 0, 16))
|
||||
>Common : Symbol(Common, Decl(bug24703.js, 0, 3), Decl(bug24703.js, 0, 16))
|
||||
>I : Symbol(Common.I, Decl(bug24703.js, 0, 16))
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
>super : Symbol(I, Decl(bug24703.js, 1, 10))
|
||||
|
||||
this.o = 2
|
||||
>this.o : Symbol(O.o, Decl(bug24703.js, 8, 15))
|
||||
>this : Symbol(O, Decl(bug24703.js, 6, 10))
|
||||
>o : Symbol(O.o, Decl(bug24703.js, 8, 15))
|
||||
}
|
||||
}
|
||||
var o = new Common.O()
|
||||
>o : Symbol(o, Decl(bug24703.js, 12, 3))
|
||||
>Common.O : Symbol(Common.O, Decl(bug24703.js, 5, 1))
|
||||
>Common : Symbol(Common, Decl(bug24703.js, 0, 3), Decl(bug24703.js, 0, 16))
|
||||
>O : Symbol(Common.O, Decl(bug24703.js, 5, 1))
|
||||
|
||||
var i = new Common.I()
|
||||
>i : Symbol(i, Decl(bug24703.js, 13, 3))
|
||||
>Common.I : Symbol(Common.I, Decl(bug24703.js, 0, 16))
|
||||
>Common : Symbol(Common, Decl(bug24703.js, 0, 3), Decl(bug24703.js, 0, 16))
|
||||
>I : Symbol(Common.I, Decl(bug24703.js, 0, 16))
|
||||
|
||||
o.i
|
||||
>o.i : Symbol(I.i, Decl(bug24703.js, 2, 19))
|
||||
>o : Symbol(o, Decl(bug24703.js, 12, 3))
|
||||
>i : Symbol(I.i, Decl(bug24703.js, 2, 19))
|
||||
|
||||
o.o
|
||||
>o.o : Symbol(O.o, Decl(bug24703.js, 8, 15))
|
||||
>o : Symbol(o, Decl(bug24703.js, 12, 3))
|
||||
>o : Symbol(O.o, Decl(bug24703.js, 8, 15))
|
||||
|
||||
i.i
|
||||
>i.i : Symbol(I.i, Decl(bug24703.js, 2, 19))
|
||||
>i : Symbol(i, Decl(bug24703.js, 13, 3))
|
||||
>i : Symbol(I.i, Decl(bug24703.js, 2, 19))
|
||||
|
||||
|
||||
74
tests/baselines/reference/typeFromPropertyAssignment25.types
Normal file
74
tests/baselines/reference/typeFromPropertyAssignment25.types
Normal file
@ -0,0 +1,74 @@
|
||||
=== tests/cases/conformance/salsa/bug24703.js ===
|
||||
var Common = {};
|
||||
>Common : { [x: string]: any; I: typeof I; O: typeof O; }
|
||||
>{} : { [x: string]: any; I: typeof I; O: typeof O; }
|
||||
|
||||
Common.I = class {
|
||||
>Common.I = class { constructor() { this.i = 1 }} : typeof I
|
||||
>Common.I : typeof I
|
||||
>Common : { [x: string]: any; I: typeof I; O: typeof O; }
|
||||
>I : typeof I
|
||||
>class { constructor() { this.i = 1 }} : typeof I
|
||||
|
||||
constructor() {
|
||||
this.i = 1
|
||||
>this.i = 1 : 1
|
||||
>this.i : number
|
||||
>this : this
|
||||
>i : number
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
Common.O = class extends Common.I {
|
||||
>Common.O = class extends Common.I { constructor() { super() this.o = 2 }} : typeof O
|
||||
>Common.O : typeof O
|
||||
>Common : { [x: string]: any; I: typeof I; O: typeof O; }
|
||||
>O : typeof O
|
||||
>class extends Common.I { constructor() { super() this.o = 2 }} : typeof O
|
||||
>Common.I : I
|
||||
>Common : { [x: string]: any; I: typeof I; O: typeof O; }
|
||||
>I : typeof I
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
>super() : void
|
||||
>super : typeof I
|
||||
|
||||
this.o = 2
|
||||
>this.o = 2 : 2
|
||||
>this.o : number
|
||||
>this : this
|
||||
>o : number
|
||||
>2 : 2
|
||||
}
|
||||
}
|
||||
var o = new Common.O()
|
||||
>o : O
|
||||
>new Common.O() : O
|
||||
>Common.O : typeof O
|
||||
>Common : { [x: string]: any; I: typeof I; O: typeof O; }
|
||||
>O : typeof O
|
||||
|
||||
var i = new Common.I()
|
||||
>i : I
|
||||
>new Common.I() : I
|
||||
>Common.I : typeof I
|
||||
>Common : { [x: string]: any; I: typeof I; O: typeof O; }
|
||||
>I : typeof I
|
||||
|
||||
o.i
|
||||
>o.i : number
|
||||
>o : O
|
||||
>i : number
|
||||
|
||||
o.o
|
||||
>o.o : number
|
||||
>o : O
|
||||
>o : number
|
||||
|
||||
i.i
|
||||
>i.i : number
|
||||
>i : I
|
||||
>i : number
|
||||
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
// @allowJs: true
|
||||
// @Filename: bug24703.js
|
||||
var Common = {};
|
||||
Common.I = class {
|
||||
constructor() {
|
||||
this.i = 1
|
||||
}
|
||||
}
|
||||
Common.O = class extends Common.I {
|
||||
constructor() {
|
||||
super()
|
||||
this.o = 2
|
||||
}
|
||||
}
|
||||
var o = new Common.O()
|
||||
var i = new Common.I()
|
||||
o.i
|
||||
o.o
|
||||
i.i
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user