mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Fix class/constructor-function merge (#27366)
The check for prototype assignment on constructor functions assumes
that the prototype property, if present, comes from an assignment
declaration, such as:
```js
SomeClass.prototype = { /* methods go here */ }
```
In this case, however, when class SomeClass and var SomeClass merge
(because this is allowed), prototype is the synthetic property from
class SomeClass, which has no valueDeclaration.
The fix is to check that prototype has a valueDeclaration before
checking whether the valueDeclaration is in fact a prototype-assignment
declaration.
This commit is contained in:
parent
a6a27e9de9
commit
8a4b6e03ab
@ -20459,7 +20459,7 @@ namespace ts {
|
||||
isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) ||
|
||||
isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent));
|
||||
const prototype = assignmentSymbol && assignmentSymbol.exports && assignmentSymbol.exports.get("prototype" as __String);
|
||||
const init = prototype && getAssignedJSPrototype(prototype.valueDeclaration);
|
||||
const init = prototype && prototype.valueDeclaration && getAssignedJSPrototype(prototype.valueDeclaration);
|
||||
return init ? checkExpression(init) : undefined;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
=== tests/cases/conformance/salsa/file1.js ===
|
||||
var SomeClass = function () {
|
||||
>SomeClass : Symbol(SomeClass, Decl(file1.js, 0, 3), Decl(file2.js, 0, 0), Decl(file2.js, 0, 19))
|
||||
|
||||
this.otherProp = 0;
|
||||
>otherProp : Symbol(SomeClass.otherProp, Decl(file1.js, 0, 29))
|
||||
|
||||
};
|
||||
|
||||
new SomeClass();
|
||||
>SomeClass : Symbol(SomeClass, Decl(file1.js, 0, 3), Decl(file2.js, 0, 0), Decl(file2.js, 0, 19))
|
||||
|
||||
=== tests/cases/conformance/salsa/file2.js ===
|
||||
class SomeClass { }
|
||||
>SomeClass : Symbol(SomeClass, Decl(file1.js, 0, 3), Decl(file2.js, 0, 0), Decl(file2.js, 0, 19))
|
||||
|
||||
SomeClass.prop = 0
|
||||
>SomeClass.prop : Symbol(SomeClass.prop, Decl(file2.js, 0, 19))
|
||||
>SomeClass : Symbol(SomeClass, Decl(file1.js, 0, 3), Decl(file2.js, 0, 0), Decl(file2.js, 0, 19))
|
||||
>prop : Symbol(SomeClass.prop, Decl(file2.js, 0, 19))
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
=== tests/cases/conformance/salsa/file1.js ===
|
||||
var SomeClass = function () {
|
||||
>SomeClass : typeof SomeClass
|
||||
>function () { this.otherProp = 0;} : typeof SomeClass
|
||||
|
||||
this.otherProp = 0;
|
||||
>this.otherProp = 0 : 0
|
||||
>this.otherProp : any
|
||||
>this : any
|
||||
>otherProp : any
|
||||
>0 : 0
|
||||
|
||||
};
|
||||
|
||||
new SomeClass();
|
||||
>new SomeClass() : SomeClass
|
||||
>SomeClass : typeof SomeClass
|
||||
|
||||
=== tests/cases/conformance/salsa/file2.js ===
|
||||
class SomeClass { }
|
||||
>SomeClass : SomeClass
|
||||
|
||||
SomeClass.prop = 0
|
||||
>SomeClass.prop = 0 : 0
|
||||
>SomeClass.prop : number
|
||||
>SomeClass : typeof SomeClass
|
||||
>prop : number
|
||||
>0 : 0
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
// @allowJs: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: file1.js
|
||||
var SomeClass = function () {
|
||||
this.otherProp = 0;
|
||||
};
|
||||
|
||||
new SomeClass();
|
||||
|
||||
// @Filename: file2.js
|
||||
class SomeClass { }
|
||||
SomeClass.prop = 0
|
||||
Loading…
x
Reference in New Issue
Block a user