diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 30d4c5b7c2a..9b5013e3141 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1423,9 +1423,10 @@ namespace ts { return true; } if (isUsedInFunctionOrInstanceProperty(usage, declaration)) { - if (compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions.useDefineForClassFields && getContainingClass(declaration)) { - return (isPropertyDeclaration(declaration) || isParameterPropertyDeclaration(declaration, declaration.parent)) && - !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ true); + if (compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions.useDefineForClassFields + && getContainingClass(declaration) + && (isPropertyDeclaration(declaration) || isParameterPropertyDeclaration(declaration, declaration.parent))) { + return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ true); } else { return true; diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt index 2010e92a2d8..b8d6ddc136c 100644 --- a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt @@ -1,10 +1,11 @@ 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(6,19): error TS2729: Property 'm3' is used before its initialization. +tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(12,17): error TS2729: Property 'baz' is used before its initialization. +tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(13,16): error TS2729: Property 'foo' is used before its initialization. -==== tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts (4 errors) ==== +==== tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts (5 errors) ==== class C { qux = this.bar // should error ~~~ @@ -13,20 +14,26 @@ tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterProper 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. +!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:11:17: 'foo' is declared here. quiz = this.bar // ok + quench = this.m1() // ok + quanch = this.m3() // should error + ~~ +!!! error TS2729: Property 'm3' is used before its initialization. +!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:10:5: 'm3' is declared here. m1() { this.foo // ok } + m3 = function() { } constructor(public 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. +!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:13: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. +!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:11:17: 'foo' is declared here. quid = this.baz // ok m2() { this.foo // ok diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js index f71361eb570..d4e0de0d8c5 100644 --- a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js @@ -3,9 +3,12 @@ class C { qux = this.bar // should error bar = this.foo // should error quiz = this.bar // ok + quench = this.m1() // ok + quanch = this.m3() // should error m1() { this.foo // ok } + m3 = function() { } constructor(public foo: string) {} quim = this.baz // should error baz = this.foo; // should error @@ -45,9 +48,12 @@ class C { qux = this.bar; // should error bar = this.foo; // should error quiz = this.bar; // ok + quench = this.m1(); // ok + quanch = this.m3(); // should error m1() { this.foo; // ok } + m3 = function () { }; constructor(foo) { this.foo = foo; } diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols index 5fd56137bb8..27d3f243966 100644 --- a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols @@ -10,9 +10,9 @@ class C { 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.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) >this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) ->foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) quiz = this.bar // ok >quiz : Symbol(C.quiz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 2, 18)) @@ -20,105 +20,120 @@ class C { >this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) >bar : Symbol(C.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 1, 18)) + quench = this.m1() // ok +>quench : Symbol(C.quench, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 3, 19)) +>this.m1 : Symbol(C.m1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 22)) +>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) +>m1 : Symbol(C.m1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 22)) + + quanch = this.m3() // should error +>quanch : Symbol(C.quanch, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 4, 22)) +>this.m3 : Symbol(C.m3, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 5)) +>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) +>m3 : Symbol(C.m3, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 5)) + m1() { ->m1 : Symbol(C.m1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 3, 19)) +>m1 : Symbol(C.m1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 22)) this.foo // ok ->this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) +>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) >this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) ->foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) } + m3 = function() { } +>m3 : Symbol(C.m3, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 5)) + constructor(public foo: string) {} ->foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) quim = this.baz // should error ->quim : Symbol(C.quim, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 38)) ->this.baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19)) +>quim : Symbol(C.quim, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 38)) +>this.baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 11, 19)) >this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) ->baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19)) +>baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 11, 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)) +>baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 11, 19)) +>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) >this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) ->foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) quid = this.baz // ok ->quid : Symbol(C.quid, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 9, 19)) ->this.baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19)) +>quid : Symbol(C.quid, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 12, 19)) +>this.baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 11, 19)) >this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) ->baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19)) +>baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 11, 19)) m2() { ->m2 : Symbol(C.m2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 19)) +>m2 : Symbol(C.m2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 13, 19)) this.foo // ok ->this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) +>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) >this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) ->foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) } } class D extends C { ->D : Symbol(D, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 14, 1)) +>D : Symbol(D, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 17, 1)) >C : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) quill = this.foo // ok ->quill : Symbol(D.quill, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 16, 19)) ->this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) ->this : Symbol(D, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 14, 1)) ->foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) +>quill : Symbol(D.quill, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 19, 19)) +>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) +>this : Symbol(D, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 17, 1)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 16)) } class E { ->E : Symbol(E, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 18, 1)) +>E : Symbol(E, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 21, 1)) bar = () => this.foo1 + this.foo2; // both ok ->bar : Symbol(E.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 20, 9)) ->this.foo1 : Symbol(E.foo1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 21, 38)) ->this : Symbol(E, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 18, 1)) ->foo1 : Symbol(E.foo1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 21, 38)) ->this.foo2 : Symbol(E.foo2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 23, 16)) ->this : Symbol(E, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 18, 1)) ->foo2 : Symbol(E.foo2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 23, 16)) +>bar : Symbol(E.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 23, 9)) +>this.foo1 : Symbol(E.foo1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 24, 38)) +>this : Symbol(E, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 21, 1)) +>foo1 : Symbol(E.foo1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 24, 38)) +>this.foo2 : Symbol(E.foo2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 26, 16)) +>this : Symbol(E, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 21, 1)) +>foo2 : Symbol(E.foo2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 26, 16)) foo1 = ''; ->foo1 : Symbol(E.foo1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 21, 38)) +>foo1 : Symbol(E.foo1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 24, 38)) constructor(public foo2: string) {} ->foo2 : Symbol(E.foo2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 23, 16)) +>foo2 : Symbol(E.foo2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 26, 16)) } class F { ->F : Symbol(F, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 24, 1)) +>F : Symbol(F, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 27, 1)) Inner = class extends F { ->Inner : Symbol(F.Inner, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 26, 9)) ->F : Symbol(F, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 24, 1)) +>Inner : Symbol(F.Inner, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 29, 9)) +>F : Symbol(F, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 27, 1)) p2 = this.p1 ->p2 : Symbol((Anonymous class).p2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 27, 29)) ->this.p1 : Symbol(F.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 29, 5)) ->this : Symbol((Anonymous class), Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 27, 11)) ->p1 : Symbol(F.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 29, 5)) +>p2 : Symbol((Anonymous class).p2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 30, 29)) +>this.p1 : Symbol(F.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 32, 5)) +>this : Symbol((Anonymous class), Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 30, 11)) +>p1 : Symbol(F.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 32, 5)) } p1 = 0 ->p1 : Symbol(F.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 29, 5)) +>p1 : Symbol(F.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 32, 5)) } class G { ->G : Symbol(G, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 31, 1)) +>G : Symbol(G, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 34, 1)) Inner = class extends G { ->Inner : Symbol(G.Inner, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 32, 9)) ->G : Symbol(G, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 31, 1)) +>Inner : Symbol(G.Inner, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 35, 9)) +>G : Symbol(G, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 34, 1)) p2 = this.p1 ->p2 : Symbol((Anonymous class).p2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 33, 29)) ->this.p1 : Symbol(G.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 36, 16)) ->this : Symbol((Anonymous class), Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 33, 11)) ->p1 : Symbol(G.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 36, 16)) +>p2 : Symbol((Anonymous class).p2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 36, 29)) +>this.p1 : Symbol(G.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 39, 16)) +>this : Symbol((Anonymous class), Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 36, 11)) +>p1 : Symbol(G.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 39, 16)) } constructor(public p1: number) {} ->p1 : Symbol(G.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 36, 16)) +>p1 : Symbol(G.p1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 39, 16)) } diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types index 631b0dba5a4..d4b3cd9d958 100644 --- a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types @@ -20,6 +20,20 @@ class C { >this : this >bar : string + quench = this.m1() // ok +>quench : void +>this.m1() : void +>this.m1 : () => void +>this : this +>m1 : () => void + + quanch = this.m3() // should error +>quanch : void +>this.m3() : void +>this.m3 : () => void +>this : this +>m3 : () => void + m1() { >m1 : () => void @@ -28,6 +42,10 @@ class C { >this : this >foo : string } + m3 = function() { } +>m3 : () => void +>function() { } : () => void + constructor(public foo: string) {} >foo : string diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts index f4475f09ddf..d778149c428 100644 --- a/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts @@ -4,9 +4,12 @@ class C { qux = this.bar // should error bar = this.foo // should error quiz = this.bar // ok + quench = this.m1() // ok + quanch = this.m3() // should error m1() { this.foo // ok } + m3 = function() { } constructor(public foo: string) {} quim = this.baz // should error baz = this.foo; // should error