Allow this in constructor parameter defaults when legal (#57682)

This commit is contained in:
Ryan Cavanaugh 2024-03-25 11:20:08 -07:00 committed by GitHub
parent ac962eaa1f
commit 0d4414d10d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 103 additions and 74 deletions

View File

@ -29815,12 +29815,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
error(node, Diagnostics.this_cannot_be_referenced_in_current_location);
// do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
break;
case SyntaxKind.Constructor:
if (isInConstructorArgumentInitializer(node, container)) {
error(node, Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
// do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
}
break;
}
}

View File

@ -1836,10 +1836,6 @@
"category": "Error",
"code": 2332
},
"'this' cannot be referenced in constructor arguments.": {
"category": "Error",
"code": 2333
},
"'this' cannot be referenced in a static property initializer.": {
"category": "Error",
"code": 2334

View File

@ -1,23 +1,25 @@
constructorDefaultValuesReferencingThis.ts(2,21): error TS2333: 'this' cannot be referenced in constructor arguments.
constructorDefaultValuesReferencingThis.ts(6,21): error TS2333: 'this' cannot be referenced in constructor arguments.
constructorDefaultValuesReferencingThis.ts(10,28): error TS2333: 'this' cannot be referenced in constructor arguments.
constructorDefaultValuesReferencingThis.ts(15,21): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
==== constructorDefaultValuesReferencingThis.ts (3 errors) ====
==== constructorDefaultValuesReferencingThis.ts (1 errors) ====
class C {
public baseProp = 1;
constructor(x = this) { }
~~~~
!!! error TS2333: 'this' cannot be referenced in constructor arguments.
}
class D<T> {
constructor(x = this) { }
~~~~
!!! error TS2333: 'this' cannot be referenced in constructor arguments.
}
class E<T> {
constructor(public x = this) { }
~~~~
!!! error TS2333: 'this' cannot be referenced in constructor arguments.
}
}
class F extends C {
constructor(y = this.baseProp) {
~~~~
!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
super();
}
}

View File

@ -2,6 +2,7 @@
//// [constructorDefaultValuesReferencingThis.ts]
class C {
public baseProp = 1;
constructor(x = this) { }
}
@ -11,12 +12,35 @@ class D<T> {
class E<T> {
constructor(public x = this) { }
}
}
class F extends C {
constructor(y = this.baseProp) {
super();
}
}
//// [constructorDefaultValuesReferencingThis.js]
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var C = /** @class */ (function () {
function C(x) {
if (x === void 0) { x = this; }
this.baseProp = 1;
}
return C;
}());
@ -33,3 +57,11 @@ var E = /** @class */ (function () {
}
return E;
}());
var F = /** @class */ (function (_super) {
__extends(F, _super);
function F(y) {
if (y === void 0) { y = _this.baseProp; }
return _super.call(this) || this;
}
return F;
}(C));

View File

@ -4,25 +4,44 @@
class C {
>C : Symbol(C, Decl(constructorDefaultValuesReferencingThis.ts, 0, 0))
public baseProp = 1;
>baseProp : Symbol(C.baseProp, Decl(constructorDefaultValuesReferencingThis.ts, 0, 9))
constructor(x = this) { }
>x : Symbol(x, Decl(constructorDefaultValuesReferencingThis.ts, 1, 16))
>x : Symbol(x, Decl(constructorDefaultValuesReferencingThis.ts, 2, 16))
>this : Symbol(C, Decl(constructorDefaultValuesReferencingThis.ts, 0, 0))
}
class D<T> {
>D : Symbol(D, Decl(constructorDefaultValuesReferencingThis.ts, 2, 1))
>T : Symbol(T, Decl(constructorDefaultValuesReferencingThis.ts, 4, 8))
>D : Symbol(D, Decl(constructorDefaultValuesReferencingThis.ts, 3, 1))
>T : Symbol(T, Decl(constructorDefaultValuesReferencingThis.ts, 5, 8))
constructor(x = this) { }
>x : Symbol(x, Decl(constructorDefaultValuesReferencingThis.ts, 5, 16))
>this : Symbol(D, Decl(constructorDefaultValuesReferencingThis.ts, 2, 1))
>x : Symbol(x, Decl(constructorDefaultValuesReferencingThis.ts, 6, 16))
>this : Symbol(D, Decl(constructorDefaultValuesReferencingThis.ts, 3, 1))
}
class E<T> {
>E : Symbol(E, Decl(constructorDefaultValuesReferencingThis.ts, 6, 1))
>T : Symbol(T, Decl(constructorDefaultValuesReferencingThis.ts, 8, 8))
>E : Symbol(E, Decl(constructorDefaultValuesReferencingThis.ts, 7, 1))
>T : Symbol(T, Decl(constructorDefaultValuesReferencingThis.ts, 9, 8))
constructor(public x = this) { }
>x : Symbol(E.x, Decl(constructorDefaultValuesReferencingThis.ts, 9, 16))
>this : Symbol(E, Decl(constructorDefaultValuesReferencingThis.ts, 6, 1))
>x : Symbol(E.x, Decl(constructorDefaultValuesReferencingThis.ts, 10, 16))
>this : Symbol(E, Decl(constructorDefaultValuesReferencingThis.ts, 7, 1))
}
class F extends C {
>F : Symbol(F, Decl(constructorDefaultValuesReferencingThis.ts, 11, 1))
>C : Symbol(C, Decl(constructorDefaultValuesReferencingThis.ts, 0, 0))
constructor(y = this.baseProp) {
>y : Symbol(y, Decl(constructorDefaultValuesReferencingThis.ts, 14, 16))
>this.baseProp : Symbol(C.baseProp, Decl(constructorDefaultValuesReferencingThis.ts, 0, 9))
>this : Symbol(F, Decl(constructorDefaultValuesReferencingThis.ts, 11, 1))
>baseProp : Symbol(C.baseProp, Decl(constructorDefaultValuesReferencingThis.ts, 0, 9))
super();
>super : Symbol(C, Decl(constructorDefaultValuesReferencingThis.ts, 0, 0))
}
}

View File

@ -4,6 +4,10 @@
class C {
>C : C
public baseProp = 1;
>baseProp : number
>1 : 1
constructor(x = this) { }
>x : this
>this : this
@ -24,3 +28,20 @@ class E<T> {
>x : this
>this : this
}
class F extends C {
>F : F
>C : C
constructor(y = this.baseProp) {
>y : number
>this.baseProp : number
>this : this
>baseProp : number
super();
>super() : void
>super : typeof C
}
}

View File

@ -1,10 +0,0 @@
thisInConstructorParameter1.ts(3,21): error TS2333: 'this' cannot be referenced in constructor arguments.
==== thisInConstructorParameter1.ts (1 errors) ====
class Foo {
public y;
constructor(x = this.y) { }
~~~~
!!! error TS2333: 'this' cannot be referenced in constructor arguments.
}

View File

@ -1,20 +0,0 @@
thisInConstructorParameter2.ts(5,28): error TS2333: 'this' cannot be referenced in constructor arguments.
thisInConstructorParameter2.ts(5,39): error TS2333: 'this' cannot be referenced in constructor arguments.
==== thisInConstructorParameter2.ts (2 errors) ====
class P {
x = this;
static y = this;
constructor(public z = this, zz = this, zzz = (p = this) => this) {
~~~~
!!! error TS2333: 'this' cannot be referenced in constructor arguments.
~~~~
!!! error TS2333: 'this' cannot be referenced in constructor arguments.
zzz = (p = this) => this;
}
foo(zz = this) { zz.x; }
static bar(zz = this) { zz.y; }
}

View File

@ -1,12 +0,0 @@
typeOfThisInConstructorParamList.ts(4,21): error TS2333: 'this' cannot be referenced in constructor arguments.
==== typeOfThisInConstructorParamList.ts (1 errors) ====
//type of 'this' in constructor param list is the class instance type (error)
class ErrClass {
// Should be an error
constructor(f = this) { }
~~~~
!!! error TS2333: 'this' cannot be referenced in constructor arguments.
}

View File

@ -1,4 +1,5 @@
class C {
public baseProp = 1;
constructor(x = this) { }
}
@ -8,4 +9,10 @@ class D<T> {
class E<T> {
constructor(public x = this) { }
}
}
class F extends C {
constructor(y = this.baseProp) {
super();
}
}