mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
fix(51521): Using a of property declared after an initializing constructor triggers an assertion failure in JS (#51524)
Fixes https://github.com/microsoft/TypeScript/issues/51521
This commit is contained in:
@@ -3531,7 +3531,7 @@ export function isSpecialPropertyDeclaration(expr: PropertyAccessExpression | El
|
||||
export function setValueDeclaration(symbol: Symbol, node: Declaration): void {
|
||||
const { valueDeclaration } = symbol;
|
||||
if (!valueDeclaration ||
|
||||
!(node.flags & NodeFlags.Ambient && !(valueDeclaration.flags & NodeFlags.Ambient)) &&
|
||||
!(node.flags & NodeFlags.Ambient && !isInJSFile(node) && !(valueDeclaration.flags & NodeFlags.Ambient)) &&
|
||||
(isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) ||
|
||||
(valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) {
|
||||
// other kinds of value declarations take precedence over modules and assignment declarations
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/test.js(3,9): error TS2322: Type '{}' is not assignable to type 'string'.
|
||||
/test.js(6,5): error TS8009: The 'declare' modifier can only be used in TypeScript files.
|
||||
/test.js(6,19): error TS8010: Type annotations can only be used in TypeScript files.
|
||||
/test.js(9,19): error TS2339: Property 'foo' does not exist on type 'string'.
|
||||
|
||||
|
||||
==== /test.js (4 errors) ====
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.prop = {};
|
||||
~~~~~~~~~
|
||||
!!! error TS2322: Type '{}' is not assignable to type 'string'.
|
||||
}
|
||||
|
||||
declare prop: string;
|
||||
~~~~~~~
|
||||
!!! error TS8009: The 'declare' modifier can only be used in TypeScript files.
|
||||
~~~~~~
|
||||
!!! error TS8010: Type annotations can only be used in TypeScript files.
|
||||
|
||||
method() {
|
||||
this.prop.foo
|
||||
~~~
|
||||
!!! error TS2339: Property 'foo' does not exist on type 'string'.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
=== /test.js ===
|
||||
class Foo {
|
||||
>Foo : Symbol(Foo, Decl(test.js, 0, 0))
|
||||
|
||||
constructor() {
|
||||
this.prop = {};
|
||||
>this.prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
|
||||
>this : Symbol(Foo, Decl(test.js, 0, 0))
|
||||
>prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
|
||||
}
|
||||
|
||||
declare prop: string;
|
||||
>prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
|
||||
|
||||
method() {
|
||||
>method : Symbol(Foo.method, Decl(test.js, 5, 25))
|
||||
|
||||
this.prop.foo
|
||||
>this.prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
|
||||
>this : Symbol(Foo, Decl(test.js, 0, 0))
|
||||
>prop : Symbol(Foo.prop, Decl(test.js, 1, 19), Decl(test.js, 3, 5))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
=== /test.js ===
|
||||
class Foo {
|
||||
>Foo : Foo
|
||||
|
||||
constructor() {
|
||||
this.prop = {};
|
||||
>this.prop = {} : {}
|
||||
>this.prop : string
|
||||
>this : this
|
||||
>prop : string
|
||||
>{} : {}
|
||||
}
|
||||
|
||||
declare prop: string;
|
||||
>prop : string
|
||||
|
||||
method() {
|
||||
>method : () => void
|
||||
|
||||
this.prop.foo
|
||||
>this.prop.foo : any
|
||||
>this.prop : string
|
||||
>this : this
|
||||
>prop : string
|
||||
>foo : any
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
=== /a.js ===
|
||||
// class C {
|
||||
// constructor() {
|
||||
// this.prop = "";
|
||||
// }
|
||||
// declare prop: string;
|
||||
// method() {
|
||||
// this.prop.foo
|
||||
// ^^^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | any
|
||||
// | ----------------------------------------------------------------------
|
||||
// }
|
||||
// }
|
||||
|
||||
[
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/a.js",
|
||||
"position": 122,
|
||||
"name": ""
|
||||
},
|
||||
"item": {
|
||||
"kind": "",
|
||||
"kindModifiers": "",
|
||||
"textSpan": {
|
||||
"start": 119,
|
||||
"length": 3
|
||||
},
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "any",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
16
tests/cases/compiler/ambientPropertyDeclarationInJs.ts
Normal file
16
tests/cases/compiler/ambientPropertyDeclarationInJs.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @filename: /test.js
|
||||
|
||||
class Foo {
|
||||
constructor() {
|
||||
this.prop = {};
|
||||
}
|
||||
|
||||
declare prop: string;
|
||||
|
||||
method() {
|
||||
this.prop.foo
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowJs: true
|
||||
// @filename: /a.js
|
||||
////class C {
|
||||
//// constructor() {
|
||||
//// this.prop = "";
|
||||
//// }
|
||||
//// declare prop: string;
|
||||
//// method() {
|
||||
//// this.prop.foo/**/
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.baselineQuickInfo();
|
||||
Reference in New Issue
Block a user