Skip to content

Commit 1d81c1d

Browse files
authored
fix(51521): Using a of property declared after an initializing constructor triggers an assertion failure in JS (microsoft#51524)
Fixes microsoft#51521
1 parent f576398 commit 1d81c1d

7 files changed

+149
-1
lines changed

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3531,7 +3531,7 @@ export function isSpecialPropertyDeclaration(expr: PropertyAccessExpression | El
35313531
export function setValueDeclaration(symbol: Symbol, node: Declaration): void {
35323532
const { valueDeclaration } = symbol;
35333533
if (!valueDeclaration ||
3534-
!(node.flags & NodeFlags.Ambient && !(valueDeclaration.flags & NodeFlags.Ambient)) &&
3534+
!(node.flags & NodeFlags.Ambient && !isInJSFile(node) && !(valueDeclaration.flags & NodeFlags.Ambient)) &&
35353535
(isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) ||
35363536
(valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) {
35373537
// other kinds of value declarations take precedence over modules and assignment declarations
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/test.js(3,9): error TS2322: Type '{}' is not assignable to type 'string'.
2+
/test.js(6,5): error TS8009: The 'declare' modifier can only be used in TypeScript files.
3+
/test.js(6,19): error TS8010: Type annotations can only be used in TypeScript files.
4+
/test.js(9,19): error TS2339: Property 'foo' does not exist on type 'string'.
5+
6+
7+
==== /test.js (4 errors) ====
8+
class Foo {
9+
constructor() {
10+
this.prop = {};
11+
~~~~~~~~~
12+
!!! error TS2322: Type '{}' is not assignable to type 'string'.
13+
}
14+
15+
declare prop: string;
16+
~~~~~~~
17+
!!! error TS8009: The 'declare' modifier can only be used in TypeScript files.
18+
~~~~~~
19+
!!! error TS8010: Type annotations can only be used in TypeScript files.
20+
21+
method() {
22+
this.prop.foo
23+
~~~
24+
!!! error TS2339: Property 'foo' does not exist on type 'string'.
25+
}
26+
}
27+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== /test.js ===
2+
class Foo {
3+
>Foo : Symbol(Foo, Decl(test.js, 0, 0))
4+
5+
constructor() {
6+
this.prop = {};
7+
>this.prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
8+
>this : Symbol(Foo, Decl(test.js, 0, 0))
9+
>prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
10+
}
11+
12+
declare prop: string;
13+
>prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
14+
15+
method() {
16+
>method : Symbol(Foo.method, Decl(test.js, 5, 25))
17+
18+
this.prop.foo
19+
>this.prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
20+
>this : Symbol(Foo, Decl(test.js, 0, 0))
21+
>prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
22+
}
23+
}
24+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
=== /test.js ===
2+
class Foo {
3+
>Foo : Foo
4+
5+
constructor() {
6+
this.prop = {};
7+
>this.prop = {} : {}
8+
>this.prop : string
9+
>this : this
10+
>prop : string
11+
>{} : {}
12+
}
13+
14+
declare prop: string;
15+
>prop : string
16+
17+
method() {
18+
>method : () => void
19+
20+
this.prop.foo
21+
>this.prop.foo : any
22+
>this.prop : string
23+
>this : this
24+
>prop : string
25+
>foo : any
26+
}
27+
}
28+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
=== /a.js ===
2+
// class C {
3+
// constructor() {
4+
// this.prop = "";
5+
// }
6+
// declare prop: string;
7+
// method() {
8+
// this.prop.foo
9+
// ^^^
10+
// | ----------------------------------------------------------------------
11+
// | any
12+
// | ----------------------------------------------------------------------
13+
// }
14+
// }
15+
16+
[
17+
{
18+
"marker": {
19+
"fileName": "/a.js",
20+
"position": 122,
21+
"name": ""
22+
},
23+
"item": {
24+
"kind": "",
25+
"kindModifiers": "",
26+
"textSpan": {
27+
"start": 119,
28+
"length": 3
29+
},
30+
"displayParts": [
31+
{
32+
"text": "any",
33+
"kind": "keyword"
34+
}
35+
]
36+
}
37+
}
38+
]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @noEmit: true
4+
// @filename: /test.js
5+
6+
class Foo {
7+
constructor() {
8+
this.prop = {};
9+
}
10+
11+
declare prop: string;
12+
13+
method() {
14+
this.prop.foo
15+
}
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @allowJs: true
4+
// @filename: /a.js
5+
////class C {
6+
//// constructor() {
7+
//// this.prop = "";
8+
//// }
9+
//// declare prop: string;
10+
//// method() {
11+
//// this.prop.foo/**/
12+
//// }
13+
////}
14+
15+
verify.baselineQuickInfo();

0 commit comments

Comments
 (0)