From af901ba91193051bc946a501f3f6620b01471809 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 26 Feb 2020 09:07:45 -0800 Subject: [PATCH] No error on `this` exprs in static property inits (#36781) No error on `this` expressions in static property declaration initialisers when targetting ESNext and with useDefineForClassFields. In this case the emit is correct and the types are correct, so the error should not be issued. --- src/compiler/checker.ts | 2 +- .../reference/thisInClassBodyStaticESNext.js | 20 +++++++++++++ .../thisInClassBodyStaticESNext.symbols | 25 +++++++++++++++++ .../thisInClassBodyStaticESNext.types | 28 +++++++++++++++++++ .../compiler/thisInClassBodyStaticESNext.ts | 11 ++++++++ 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/thisInClassBodyStaticESNext.js create mode 100644 tests/baselines/reference/thisInClassBodyStaticESNext.symbols create mode 100644 tests/baselines/reference/thisInClassBodyStaticESNext.types create mode 100644 tests/cases/compiler/thisInClassBodyStaticESNext.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 43297244e1..bde439b038 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20947,7 +20947,7 @@ namespace ts { break; case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - if (hasModifier(container, ModifierFlags.Static)) { + if (hasModifier(container, ModifierFlags.Static) && !(compilerOptions.target === ScriptTarget.ESNext && compilerOptions.useDefineForClassFields)) { error(node, Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks } diff --git a/tests/baselines/reference/thisInClassBodyStaticESNext.js b/tests/baselines/reference/thisInClassBodyStaticESNext.js new file mode 100644 index 0000000000..7f061b12a4 --- /dev/null +++ b/tests/baselines/reference/thisInClassBodyStaticESNext.js @@ -0,0 +1,20 @@ +//// [thisInClassBodyStaticESNext.ts] +// all are allowed with es-compliant class field emit +class Foo { + x = this + static t = this + static at = () => this + static ft = function () { return this } + static mt() { return this } +} + + +//// [thisInClassBodyStaticESNext.js] +// all are allowed with es-compliant class field emit +class Foo { + x = this; + static t = this; + static at = () => this; + static ft = function () { return this; }; + static mt() { return this; } +} diff --git a/tests/baselines/reference/thisInClassBodyStaticESNext.symbols b/tests/baselines/reference/thisInClassBodyStaticESNext.symbols new file mode 100644 index 0000000000..7dc9767ccd --- /dev/null +++ b/tests/baselines/reference/thisInClassBodyStaticESNext.symbols @@ -0,0 +1,25 @@ +=== tests/cases/compiler/thisInClassBodyStaticESNext.ts === +// all are allowed with es-compliant class field emit +class Foo { +>Foo : Symbol(Foo, Decl(thisInClassBodyStaticESNext.ts, 0, 0)) + + x = this +>x : Symbol(Foo.x, Decl(thisInClassBodyStaticESNext.ts, 1, 11)) +>this : Symbol(Foo, Decl(thisInClassBodyStaticESNext.ts, 0, 0)) + + static t = this +>t : Symbol(Foo.t, Decl(thisInClassBodyStaticESNext.ts, 2, 12)) +>this : Symbol(Foo, Decl(thisInClassBodyStaticESNext.ts, 0, 0)) + + static at = () => this +>at : Symbol(Foo.at, Decl(thisInClassBodyStaticESNext.ts, 3, 19)) +>this : Symbol(Foo, Decl(thisInClassBodyStaticESNext.ts, 0, 0)) + + static ft = function () { return this } +>ft : Symbol(Foo.ft, Decl(thisInClassBodyStaticESNext.ts, 4, 26)) + + static mt() { return this } +>mt : Symbol(Foo.mt, Decl(thisInClassBodyStaticESNext.ts, 5, 43)) +>this : Symbol(Foo, Decl(thisInClassBodyStaticESNext.ts, 0, 0)) +} + diff --git a/tests/baselines/reference/thisInClassBodyStaticESNext.types b/tests/baselines/reference/thisInClassBodyStaticESNext.types new file mode 100644 index 0000000000..152e3a0748 --- /dev/null +++ b/tests/baselines/reference/thisInClassBodyStaticESNext.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/thisInClassBodyStaticESNext.ts === +// all are allowed with es-compliant class field emit +class Foo { +>Foo : Foo + + x = this +>x : this +>this : this + + static t = this +>t : typeof Foo +>this : typeof Foo + + static at = () => this +>at : () => typeof Foo +>() => this : () => typeof Foo +>this : typeof Foo + + static ft = function () { return this } +>ft : () => any +>function () { return this } : () => any +>this : any + + static mt() { return this } +>mt : () => typeof Foo +>this : typeof Foo +} + diff --git a/tests/cases/compiler/thisInClassBodyStaticESNext.ts b/tests/cases/compiler/thisInClassBodyStaticESNext.ts new file mode 100644 index 0000000000..ae72e6f0bd --- /dev/null +++ b/tests/cases/compiler/thisInClassBodyStaticESNext.ts @@ -0,0 +1,11 @@ +// @target: esnext +// @useDefineForClassFields: true + +// all are allowed with es-compliant class field emit +class Foo { + x = this + static t = this + static at = () => this + static ft = function () { return this } + static mt() { return this } +}