Compare commits
2 commits
main
...
assign-par
Author | SHA1 | Date | |
---|---|---|---|
09f409cfcb | |||
231d0d1be4 |
|
@ -1328,6 +1328,11 @@ namespace ts {
|
|||
// still might be illegal if a self-referencing property initializer (eg private x = this.x)
|
||||
return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage);
|
||||
}
|
||||
else if (isParameterPropertyDeclaration(declaration, declaration.parent)) {
|
||||
// foo = this.bar is illegal in esnext+useDefineForClassFields when bar is a parameter property
|
||||
return !(compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions.useDefineForClassFields
|
||||
&& isUsedInFunctionOrInstanceProperty(usage, declaration));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1336,6 +1341,7 @@ namespace ts {
|
|||
// 1. inside an export specifier
|
||||
// 2. inside a function
|
||||
// 3. inside an instance property initializer, a reference to a non-instance property
|
||||
// (except when target: "esnext" and useDefineForClassFields: true and the reference is to a parameter property)
|
||||
// 4. inside a static property initializer, a reference to a static method in the same class
|
||||
// 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ)
|
||||
// or if usage is in a type context:
|
||||
|
@ -1351,7 +1357,10 @@ namespace ts {
|
|||
}
|
||||
|
||||
const container = getEnclosingBlockScopeContainer(declaration);
|
||||
return !!(usage.flags & NodeFlags.JSDoc) || isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
|
||||
return !!(usage.flags & NodeFlags.JSDoc)
|
||||
|| isInTypeQuery(usage)
|
||||
|| isUsedInFunctionOrInstanceProperty(usage, declaration, container)
|
||||
&& !(compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions.useDefineForClassFields);
|
||||
|
||||
function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean {
|
||||
const container = getEnclosingBlockScopeContainer(declaration);
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(2,16): error TS2729: Property 'bar' is used before its initialization.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(3,16): error TS2729: Property 'foo' is used before its initialization.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(9,17): error TS2729: Property 'baz' is used before its initialization.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(10,16): error TS2729: Property 'foo' is used before its initialization.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts (4 errors) ====
|
||||
class C {
|
||||
qux = this.bar // should error
|
||||
~~~
|
||||
!!! error TS2729: Property 'bar' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:3:5: 'bar' is declared here.
|
||||
bar = this.foo // should error
|
||||
~~~
|
||||
!!! error TS2729: Property 'foo' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:8:17: 'foo' is declared here.
|
||||
quiz = this.bar // ok
|
||||
m1() {
|
||||
this.foo // ok
|
||||
}
|
||||
constructor(private foo: string) {}
|
||||
quim = this.baz // should error
|
||||
~~~
|
||||
!!! error TS2729: Property 'baz' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:10:5: 'baz' is declared here.
|
||||
baz = this.foo; // should error
|
||||
~~~
|
||||
!!! error TS2729: Property 'foo' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:8:17: 'foo' is declared here.
|
||||
quid = this.baz // ok
|
||||
m2() {
|
||||
this.foo // ok
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
//// [assignParameterPropertyToPropertyDeclarationESNext.ts]
|
||||
class C {
|
||||
qux = this.bar // should error
|
||||
bar = this.foo // should error
|
||||
quiz = this.bar // ok
|
||||
m1() {
|
||||
this.foo // ok
|
||||
}
|
||||
constructor(private foo: string) {}
|
||||
quim = this.baz // should error
|
||||
baz = this.foo; // should error
|
||||
quid = this.baz // ok
|
||||
m2() {
|
||||
this.foo // ok
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [assignParameterPropertyToPropertyDeclarationESNext.js]
|
||||
class C {
|
||||
foo;
|
||||
qux = this.bar; // should error
|
||||
bar = this.foo; // should error
|
||||
quiz = this.bar; // ok
|
||||
m1() {
|
||||
this.foo; // ok
|
||||
}
|
||||
constructor(foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
quim = this.baz; // should error
|
||||
baz = this.foo; // should error
|
||||
quid = this.baz; // ok
|
||||
m2() {
|
||||
this.foo; // ok
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
=== tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts ===
|
||||
class C {
|
||||
>C : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0))
|
||||
|
||||
qux = this.bar // should error
|
||||
>qux : Symbol(C.qux, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 9))
|
||||
>this.bar : Symbol(C.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 1, 18))
|
||||
>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0))
|
||||
>bar : Symbol(C.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 1, 18))
|
||||
|
||||
bar = this.foo // should error
|
||||
>bar : Symbol(C.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 1, 18))
|
||||
>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16))
|
||||
>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0))
|
||||
>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16))
|
||||
|
||||
quiz = this.bar // ok
|
||||
>quiz : Symbol(C.quiz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 2, 18))
|
||||
>this.bar : Symbol(C.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 1, 18))
|
||||
>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0))
|
||||
>bar : Symbol(C.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 1, 18))
|
||||
|
||||
m1() {
|
||||
>m1 : Symbol(C.m1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 3, 19))
|
||||
|
||||
this.foo // ok
|
||||
>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16))
|
||||
>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0))
|
||||
>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16))
|
||||
}
|
||||
constructor(private foo: string) {}
|
||||
>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16))
|
||||
|
||||
quim = this.baz // should error
|
||||
>quim : Symbol(C.quim, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 39))
|
||||
>this.baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19))
|
||||
>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0))
|
||||
>baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19))
|
||||
|
||||
baz = this.foo; // should error
|
||||
>baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19))
|
||||
>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16))
|
||||
>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0))
|
||||
>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16))
|
||||
|
||||
quid = this.baz // ok
|
||||
>quid : Symbol(C.quid, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 9, 19))
|
||||
>this.baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19))
|
||||
>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0))
|
||||
>baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19))
|
||||
|
||||
m2() {
|
||||
>m2 : Symbol(C.m2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 19))
|
||||
|
||||
this.foo // ok
|
||||
>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16))
|
||||
>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0))
|
||||
>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
=== tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts ===
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
qux = this.bar // should error
|
||||
>qux : string
|
||||
>this.bar : string
|
||||
>this : this
|
||||
>bar : string
|
||||
|
||||
bar = this.foo // should error
|
||||
>bar : string
|
||||
>this.foo : string
|
||||
>this : this
|
||||
>foo : string
|
||||
|
||||
quiz = this.bar // ok
|
||||
>quiz : string
|
||||
>this.bar : string
|
||||
>this : this
|
||||
>bar : string
|
||||
|
||||
m1() {
|
||||
>m1 : () => void
|
||||
|
||||
this.foo // ok
|
||||
>this.foo : string
|
||||
>this : this
|
||||
>foo : string
|
||||
}
|
||||
constructor(private foo: string) {}
|
||||
>foo : string
|
||||
|
||||
quim = this.baz // should error
|
||||
>quim : string
|
||||
>this.baz : string
|
||||
>this : this
|
||||
>baz : string
|
||||
|
||||
baz = this.foo; // should error
|
||||
>baz : string
|
||||
>this.foo : string
|
||||
>this : this
|
||||
>foo : string
|
||||
|
||||
quid = this.baz // ok
|
||||
>quid : string
|
||||
>this.baz : string
|
||||
>this : this
|
||||
>baz : string
|
||||
|
||||
m2() {
|
||||
>m2 : () => void
|
||||
|
||||
this.foo // ok
|
||||
>this.foo : string
|
||||
>this : this
|
||||
>foo : string
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts(3,14): error TS2729: Property 'y' is used before its initialization.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts(10,14): error TS2729: Property 'y' is used before its initialization.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts(18,14): error TS2729: Property 'ka' is used before its initialization.
|
||||
tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts(22,15): error TS2729: Property 'ka' is used before its initialization.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts (4 errors) ====
|
||||
var x: "p" = "p"
|
||||
class A {
|
||||
a = this.y
|
||||
~
|
||||
!!! error TS2729: Property 'y' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts:9:17: 'y' is declared here.
|
||||
b
|
||||
public c;
|
||||
["computed"] = 13
|
||||
;[x] = 14
|
||||
m() { }
|
||||
constructor(public readonly y: number) { }
|
||||
z = this.y
|
||||
~
|
||||
!!! error TS2729: Property 'y' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts:9:17: 'y' is declared here.
|
||||
declare notEmitted;
|
||||
}
|
||||
class B {
|
||||
public a;
|
||||
}
|
||||
class C extends B {
|
||||
declare public a;
|
||||
z = this.ka
|
||||
~~
|
||||
!!! error TS2729: Property 'ka' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts:19:17: 'ka' is declared here.
|
||||
constructor(public ka: number) {
|
||||
super()
|
||||
}
|
||||
ki = this.ka
|
||||
~~
|
||||
!!! error TS2729: Property 'ka' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts:19:17: 'ka' is declared here.
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// @useDefineForClassFields: true
|
||||
// @target: esnext
|
||||
class C {
|
||||
qux = this.bar // should error
|
||||
bar = this.foo // should error
|
||||
quiz = this.bar // ok
|
||||
m1() {
|
||||
this.foo // ok
|
||||
}
|
||||
constructor(private foo: string) {}
|
||||
quim = this.baz // should error
|
||||
baz = this.foo; // should error
|
||||
quid = this.baz // ok
|
||||
m2() {
|
||||
this.foo // ok
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue