From 231d0d1be4e9e34dfd188e2190f2e7f88e53d19a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 24 Jan 2020 13:55:46 -0800 Subject: [PATCH 1/2] ESNext+[[Define]]: reference to param props illegal When target: "esnext" and useDefineForClassFields: true, property declaration initialisers should not be able to reference parameter properties; class fields are initialised before the constructor runs, but parameter properties are not: ```ts class C { foo = this.bar constructor(public bar: string) { } } ``` emits code that looks like this: ```js class C { bar foo = this.bar constructor(bar) { this.bar = bar } } new C('x').foo.length // crashes; foo is undefined ``` This PR adds an error on foo's declaration with ESNext+[[Define]]. --- src/compiler/checker.ts | 11 ++++- ...ertyToPropertyDeclarationESNext.errors.txt | 23 ++++++++++ ...eterPropertyToPropertyDeclarationESNext.js | 29 +++++++++++++ ...ropertyToPropertyDeclarationESNext.symbols | 37 ++++++++++++++++ ...rPropertyToPropertyDeclarationESNext.types | 37 ++++++++++++++++ .../defineProperty(target=esnext).errors.txt | 43 +++++++++++++++++++ ...eterPropertyToPropertyDeclarationESNext.ts | 13 ++++++ 7 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt create mode 100644 tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js create mode 100644 tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols create mode 100644 tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types create mode 100644 tests/baselines/reference/defineProperty(target=esnext).errors.txt create mode 100644 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b719fcb9b673e..6e70c19e00573 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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); diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt new file mode 100644 index 0000000000000..46474af1d39db --- /dev/null +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt @@ -0,0 +1,23 @@ +tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(2,16): error TS2729: Property 'foo' is used before its initialization. +tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(7,16): error TS2729: Property 'foo' is used before its initialization. + + +==== tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts (2 errors) ==== + class C { + bar = this.foo // should error + ~~~ +!!! error TS2729: Property 'foo' is used before its initialization. +!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:6:17: 'foo' is declared here. + m1() { + this.foo // ok + } + constructor(private foo: string) {} + baz = this.foo; // should error + ~~~ +!!! error TS2729: Property 'foo' is used before its initialization. +!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:6:17: 'foo' is declared here. + m2() { + this.foo // ok + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js new file mode 100644 index 0000000000000..4766685288326 --- /dev/null +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js @@ -0,0 +1,29 @@ +//// [assignParameterPropertyToPropertyDeclarationESNext.ts] +class C { + bar = this.foo // should error + m1() { + this.foo // ok + } + constructor(private foo: string) {} + baz = this.foo; // should error + m2() { + this.foo // ok + } +} + + +//// [assignParameterPropertyToPropertyDeclarationESNext.js] +class C { + foo; + bar = this.foo; // should error + m1() { + this.foo; // ok + } + constructor(foo) { + this.foo = foo; + } + baz = this.foo; // should error + m2() { + this.foo; // ok + } +} diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols new file mode 100644 index 0000000000000..2eb18d3e01c38 --- /dev/null +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols @@ -0,0 +1,37 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts === +class C { +>C : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) + + bar = this.foo // should error +>bar : Symbol(C.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 9)) +>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) + + m1() { +>m1 : Symbol(C.m1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 1, 18)) + + this.foo // ok +>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) + } + constructor(private foo: string) {} +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) + + baz = this.foo; // should error +>baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 39)) +>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) + + m2() { +>m2 : Symbol(C.m2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 6, 19)) + + this.foo // ok +>this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>this : Symbol(C, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 0, 0)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) + } +} + diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types new file mode 100644 index 0000000000000..f3d8c702b71fc --- /dev/null +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts === +class C { +>C : C + + bar = this.foo // should error +>bar : string +>this.foo : string +>this : this +>foo : string + + m1() { +>m1 : () => void + + this.foo // ok +>this.foo : string +>this : this +>foo : string + } + constructor(private foo: string) {} +>foo : string + + baz = this.foo; // should error +>baz : string +>this.foo : string +>this : this +>foo : string + + m2() { +>m2 : () => void + + this.foo // ok +>this.foo : string +>this : this +>foo : string + } +} + diff --git a/tests/baselines/reference/defineProperty(target=esnext).errors.txt b/tests/baselines/reference/defineProperty(target=esnext).errors.txt new file mode 100644 index 0000000000000..2a4e17a1b5b31 --- /dev/null +++ b/tests/baselines/reference/defineProperty(target=esnext).errors.txt @@ -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. + } + \ No newline at end of file diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts new file mode 100644 index 0000000000000..99e804cd7feae --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts @@ -0,0 +1,13 @@ +// @useDefineForClassFields: true +// @target: esnext +class C { + bar = this.foo // should error + m1() { + this.foo // ok + } + constructor(private foo: string) {} + baz = this.foo; // should error + m2() { + this.foo // ok + } +} From 09f409cfcb75df76803702664cec2b67046a4dde Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 24 Jan 2020 14:04:37 -0800 Subject: [PATCH 2/2] improve test --- ...ertyToPropertyDeclarationESNext.errors.txt | 22 ++++++-- ...eterPropertyToPropertyDeclarationESNext.js | 8 +++ ...ropertyToPropertyDeclarationESNext.symbols | 50 ++++++++++++++----- ...rPropertyToPropertyDeclarationESNext.types | 24 +++++++++ ...eterPropertyToPropertyDeclarationESNext.ts | 4 ++ 5 files changed, 90 insertions(+), 18 deletions(-) diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt index 46474af1d39db..e3eea9a6cc6c1 100644 --- a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.errors.txt @@ -1,21 +1,33 @@ -tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(2,16): error TS2729: Property 'foo' is used before its initialization. -tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts(7,16): error TS2729: Property 'foo' is used before its initialization. +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 (2 errors) ==== +==== 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:6:17: 'foo' is declared here. +!!! 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:6:17: 'foo' is declared here. +!!! related TS2728 tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts:8: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 4766685288326..de93aa1e43e8d 100644 --- a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.js @@ -1,11 +1,15 @@ //// [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 } @@ -15,14 +19,18 @@ class C { //// [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 } diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols index 2eb18d3e01c38..ffd908df671be 100644 --- a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.symbols @@ -2,36 +2,60 @@ 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, 0, 9)) ->this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>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)) ->foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>bar : Symbol(C.bar, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 1, 18)) m1() { ->m1 : Symbol(C.m1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 1, 18)) +>m1 : Symbol(C.m1, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 3, 19)) this.foo // ok ->this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>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, 5, 16)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) } constructor(private foo: string) {} ->foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>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, 5, 39)) ->this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>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)) ->foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>baz : Symbol(C.baz, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 8, 19)) m2() { ->m2 : Symbol(C.m2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 6, 19)) +>m2 : Symbol(C.m2, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 10, 19)) this.foo // ok ->this.foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 5, 16)) +>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, 5, 16)) +>foo : Symbol(C.foo, Decl(assignParameterPropertyToPropertyDeclarationESNext.ts, 7, 16)) } } diff --git a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types index f3d8c702b71fc..8379bda4ef700 100644 --- a/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types +++ b/tests/baselines/reference/assignParameterPropertyToPropertyDeclarationESNext.types @@ -2,12 +2,24 @@ 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 @@ -19,12 +31,24 @@ class C { 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 diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts index 99e804cd7feae..8cb56c0cd9a35 100644 --- a/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/assignParameterPropertyToPropertyDeclarationESNext.ts @@ -1,12 +1,16 @@ // @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 }