fix(49719): Incorrect error 2301 when using ES standard class properties (#49725)

* fix(49719): omit TS2301 error with enabled usedefineforclassfields

* show error for target lower than esnext with useddefineforclassfields enabled

* change target from esnext to es2022
This commit is contained in:
Oleksandr T
2022-07-21 00:36:35 +03:00
committed by GitHub
parent 2f51a9e859
commit 5702941c2f
18 changed files with 232 additions and 2 deletions

View File

@@ -2191,7 +2191,7 @@ namespace ts {
// 1. When result is undefined, after checking for a missing "this."
// 2. When result is defined
function checkAndReportErrorForInvalidInitializer() {
if (propertyWithInvalidInitializer && !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields)) {
if (propertyWithInvalidInitializer && !(useDefineForClassFields && getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2022)) {
// We have a match, but the reference occurred within a property initializer and the identifier also binds
// to a local variable in the constructor where the code will be emitted. Note that this is actually allowed
// with ESNext+useDefineForClassFields because the scope semantics are different.

View File

@@ -141,7 +141,8 @@ namespace Harness {
"preserveConstEnums",
"skipLibCheck",
"exactOptionalPropertyTypes",
"useUnknownInCatchVariables"
"useDefineForClassFields",
"useUnknownInCatchVariables",
];
private fileName: string;
private justName: string;

View File

@@ -0,0 +1,12 @@
tests/cases/compiler/classMemberInitializerScoping2.ts(3,9): error TS2301: Initializer of instance member variable 'p' cannot reference identifier 'x' declared in the constructor.
==== tests/cases/compiler/classMemberInitializerScoping2.ts (1 errors) ====
const x = 1
class C {
p = x
~
!!! error TS2301: Initializer of instance member variable 'p' cannot reference identifier 'x' declared in the constructor.
constructor(x: string) { }
}

View File

@@ -0,0 +1,15 @@
//// [classMemberInitializerScoping2.ts]
const x = 1
class C {
p = x
constructor(x: string) { }
}
//// [classMemberInitializerScoping2.js]
const x = 1;
class C {
constructor(x) {
this.p = x;
}
}

View File

@@ -0,0 +1,14 @@
=== tests/cases/compiler/classMemberInitializerScoping2.ts ===
const x = 1
>x : Symbol(x, Decl(classMemberInitializerScoping2.ts, 0, 5))
class C {
>C : Symbol(C, Decl(classMemberInitializerScoping2.ts, 0, 11))
p = x
>p : Symbol(C.p, Decl(classMemberInitializerScoping2.ts, 1, 9))
constructor(x: string) { }
>x : Symbol(x, Decl(classMemberInitializerScoping2.ts, 3, 16))
}

View File

@@ -0,0 +1,16 @@
=== tests/cases/compiler/classMemberInitializerScoping2.ts ===
const x = 1
>x : 1
>1 : 1
class C {
>C : C
p = x
>p : any
>x : any
constructor(x: string) { }
>x : string
}

View File

@@ -0,0 +1,12 @@
tests/cases/compiler/classMemberInitializerScoping2.ts(3,9): error TS2301: Initializer of instance member variable 'p' cannot reference identifier 'x' declared in the constructor.
==== tests/cases/compiler/classMemberInitializerScoping2.ts (1 errors) ====
const x = 1
class C {
p = x
~
!!! error TS2301: Initializer of instance member variable 'p' cannot reference identifier 'x' declared in the constructor.
constructor(x: string) { }
}

View File

@@ -0,0 +1,20 @@
//// [classMemberInitializerScoping2.ts]
const x = 1
class C {
p = x
constructor(x: string) { }
}
//// [classMemberInitializerScoping2.js]
const x = 1;
class C {
constructor(x) {
Object.defineProperty(this, "p", {
enumerable: true,
configurable: true,
writable: true,
value: x
});
}
}

View File

@@ -0,0 +1,14 @@
=== tests/cases/compiler/classMemberInitializerScoping2.ts ===
const x = 1
>x : Symbol(x, Decl(classMemberInitializerScoping2.ts, 0, 5))
class C {
>C : Symbol(C, Decl(classMemberInitializerScoping2.ts, 0, 11))
p = x
>p : Symbol(C.p, Decl(classMemberInitializerScoping2.ts, 1, 9))
constructor(x: string) { }
>x : Symbol(x, Decl(classMemberInitializerScoping2.ts, 3, 16))
}

View File

@@ -0,0 +1,16 @@
=== tests/cases/compiler/classMemberInitializerScoping2.ts ===
const x = 1
>x : 1
>1 : 1
class C {
>C : C
p = x
>p : any
>x : any
constructor(x: string) { }
>x : string
}

View File

@@ -0,0 +1,12 @@
tests/cases/compiler/classMemberInitializerScoping2.ts(3,9): error TS2301: Initializer of instance member variable 'p' cannot reference identifier 'x' declared in the constructor.
==== tests/cases/compiler/classMemberInitializerScoping2.ts (1 errors) ====
const x = 1
class C {
p = x
~
!!! error TS2301: Initializer of instance member variable 'p' cannot reference identifier 'x' declared in the constructor.
constructor(x: string) { }
}

View File

@@ -0,0 +1,15 @@
//// [classMemberInitializerScoping2.ts]
const x = 1
class C {
p = x
constructor(x: string) { }
}
//// [classMemberInitializerScoping2.js]
const x = 1;
class C {
constructor(x) {
this.p = x;
}
}

View File

@@ -0,0 +1,14 @@
=== tests/cases/compiler/classMemberInitializerScoping2.ts ===
const x = 1
>x : Symbol(x, Decl(classMemberInitializerScoping2.ts, 0, 5))
class C {
>C : Symbol(C, Decl(classMemberInitializerScoping2.ts, 0, 11))
p = x
>p : Symbol(C.p, Decl(classMemberInitializerScoping2.ts, 1, 9))
constructor(x: string) { }
>x : Symbol(x, Decl(classMemberInitializerScoping2.ts, 3, 16))
}

View File

@@ -0,0 +1,16 @@
=== tests/cases/compiler/classMemberInitializerScoping2.ts ===
const x = 1
>x : 1
>1 : 1
class C {
>C : C
p = x
>p : any
>x : any
constructor(x: string) { }
>x : string
}

View File

@@ -0,0 +1,14 @@
//// [classMemberInitializerScoping2.ts]
const x = 1
class C {
p = x
constructor(x: string) { }
}
//// [classMemberInitializerScoping2.js]
const x = 1;
class C {
p = x;
constructor(x) { }
}

View File

@@ -0,0 +1,15 @@
=== tests/cases/compiler/classMemberInitializerScoping2.ts ===
const x = 1
>x : Symbol(x, Decl(classMemberInitializerScoping2.ts, 0, 5))
class C {
>C : Symbol(C, Decl(classMemberInitializerScoping2.ts, 0, 11))
p = x
>p : Symbol(C.p, Decl(classMemberInitializerScoping2.ts, 1, 9))
>x : Symbol(x, Decl(classMemberInitializerScoping2.ts, 0, 5))
constructor(x: string) { }
>x : Symbol(x, Decl(classMemberInitializerScoping2.ts, 3, 16))
}

View File

@@ -0,0 +1,16 @@
=== tests/cases/compiler/classMemberInitializerScoping2.ts ===
const x = 1
>x : 1
>1 : 1
class C {
>C : C
p = x
>p : number
>x : 1
constructor(x: string) { }
>x : string
}

View File

@@ -0,0 +1,8 @@
// @target: es2017,esnext
// @useDefineForClassFields: true,false
const x = 1
class C {
p = x
constructor(x: string) { }
}