Skip to content

Commit 14774d6

Browse files
Merge pull request #9305 from RyanCavanaugh/fix9293
Properly detect circular constructor-declared `this` properties (JS)
2 parents 3f6010c + 66c3093 commit 14774d6

12 files changed

+62
-63
lines changed

src/compiler/checker.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3151,23 +3151,29 @@ namespace ts {
31513151
if (declaration.kind === SyntaxKind.ExportAssignment) {
31523152
return links.type = checkExpression((<ExportAssignment>declaration).expression);
31533153
}
3154-
// Handle module.exports = expr
3154+
// Handle variable, parameter or property
3155+
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
3156+
return unknownType;
3157+
}
3158+
3159+
let type: Type = undefined;
3160+
// Handle module.exports = expr or this.p = expr
31553161
if (declaration.kind === SyntaxKind.BinaryExpression) {
3156-
return links.type = getUnionType(map(symbol.declarations, (decl: BinaryExpression) => checkExpressionCached(decl.right)));
3162+
type = getUnionType(map(symbol.declarations, (decl: BinaryExpression) => checkExpressionCached(decl.right)));
31573163
}
3158-
if (declaration.kind === SyntaxKind.PropertyAccessExpression) {
3164+
else if (declaration.kind === SyntaxKind.PropertyAccessExpression) {
31593165
// Declarations only exist for property access expressions for certain
31603166
// special assignment kinds
31613167
if (declaration.parent.kind === SyntaxKind.BinaryExpression) {
3162-
// Handle exports.p = expr or this.p = expr or className.prototype.method = expr
3163-
return links.type = checkExpressionCached((<BinaryExpression>declaration.parent).right);
3168+
// Handle exports.p = expr or className.prototype.method = expr
3169+
type = checkExpressionCached((<BinaryExpression>declaration.parent).right);
31643170
}
31653171
}
3166-
// Handle variable, parameter or property
3167-
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
3168-
return unknownType;
3172+
3173+
if (type === undefined) {
3174+
type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
31693175
}
3170-
let type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
3176+
31713177
if (!popTypeResolution()) {
31723178
if ((<VariableLikeDeclaration>symbol.valueDeclaration).type) {
31733179
// Variable has type annotation that circularly references the variable itself

tests/baselines/reference/constDeclarations-useBeforeDefinition2.symbols

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/baselines/reference/constDeclarations-useBeforeDefinition2.types

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/compiler/foo.js ===
2+
3+
export class StackOverflowTest {
4+
>StackOverflowTest : Symbol(StackOverflowTest, Decl(foo.js, 0, 0))
5+
6+
constructor () {
7+
this.testStackOverflow = this.testStackOverflow.bind(this)
8+
>this.testStackOverflow : Symbol(StackOverflowTest.testStackOverflow, Decl(foo.js, 2, 18))
9+
>this : Symbol(StackOverflowTest, Decl(foo.js, 0, 0))
10+
>testStackOverflow : Symbol(StackOverflowTest.testStackOverflow, Decl(foo.js, 2, 18))
11+
>this.testStackOverflow : Symbol(StackOverflowTest.testStackOverflow, Decl(foo.js, 2, 18))
12+
>this : Symbol(StackOverflowTest, Decl(foo.js, 0, 0))
13+
>testStackOverflow : Symbol(StackOverflowTest.testStackOverflow, Decl(foo.js, 2, 18))
14+
>this : Symbol(StackOverflowTest, Decl(foo.js, 0, 0))
15+
}
16+
}
17+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
=== tests/cases/compiler/foo.js ===
2+
3+
export class StackOverflowTest {
4+
>StackOverflowTest : StackOverflowTest
5+
6+
constructor () {
7+
this.testStackOverflow = this.testStackOverflow.bind(this)
8+
>this.testStackOverflow = this.testStackOverflow.bind(this) : any
9+
>this.testStackOverflow : any
10+
>this : this
11+
>testStackOverflow : any
12+
>this.testStackOverflow.bind(this) : any
13+
>this.testStackOverflow.bind : any
14+
>this.testStackOverflow : any
15+
>this : this
16+
>testStackOverflow : any
17+
>bind : any
18+
>this : this
19+
}
20+
}
21+

tests/baselines/reference/letDeclarations-useBeforeDefinition2.symbols

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/baselines/reference/letDeclarations-useBeforeDefinition2.types

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/baselines/reference/transpile/Report an error when compiler-options input is empty object.errors.txt

Lines changed: 0 additions & 6 deletions
This file was deleted.

tests/baselines/reference/transpile/Report an error when compiler-options input is empty object.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

tests/baselines/reference/transpile/Report an error when compiler-options input is empty string.errors.txt

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)