diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d26da9bcbf0..8ff6712ad30 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2947,6 +2947,7 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: + case SyntaxKind.ClassStaticBlockDeclaration: // this.foo assignment in a JavaScript class // Bind this property to the containing class const containingClass = thisContainer.parent; diff --git a/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.errors.txt b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.errors.txt new file mode 100644 index 00000000000..a4729d56ef5 --- /dev/null +++ b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.errors.txt @@ -0,0 +1,30 @@ +/src/a.js(10,7): error TS2417: Class static side 'typeof ElementsArray' incorrectly extends base class static side '{ isArray(arg: any): arg is any[]; readonly prototype: any[]; }'. + Types of property 'isArray' are incompatible. + Type '(arg: any) => boolean' is not assignable to type '(arg: any) => arg is any[]'. + Signature '(arg: any): boolean' must be a type predicate. + + +==== /src/a.js (1 errors) ==== + class Thing { + static { + this.doSomething = () => {}; + } + } + + Thing.doSomething(); + + // GH#46468 + class ElementsArray extends Array { + ~~~~~~~~~~~~~ +!!! error TS2417: Class static side 'typeof ElementsArray' incorrectly extends base class static side '{ isArray(arg: any): arg is any[]; readonly prototype: any[]; }'. +!!! error TS2417: Types of property 'isArray' are incompatible. +!!! error TS2417: Type '(arg: any) => boolean' is not assignable to type '(arg: any) => arg is any[]'. +!!! error TS2417: Signature '(arg: any): boolean' must be a type predicate. + static { + const superisArray = super.isArray; + const customIsArray = (arg)=> superisArray(arg); + this.isArray = customIsArray; + } + } + + ElementsArray.isArray(new ElementsArray()); \ No newline at end of file diff --git a/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.js b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.js new file mode 100644 index 00000000000..5d25a1a9e49 --- /dev/null +++ b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.js @@ -0,0 +1,73 @@ +//// [a.js] +class Thing { + static { + this.doSomething = () => {}; + } +} + +Thing.doSomething(); + +// GH#46468 +class ElementsArray extends Array { + static { + const superisArray = super.isArray; + const customIsArray = (arg)=> superisArray(arg); + this.isArray = customIsArray; + } +} + +ElementsArray.isArray(new ElementsArray()); + +//// [a.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 _a, _b; +var _this = this; +var Thing = /** @class */ (function () { + function Thing() { + } + return Thing; +}()); +_a = Thing; +(function () { + _a.doSomething = function () { }; +})(); +Thing.doSomething(); +// GH#46468 +var ElementsArray = /** @class */ (function (_super) { + __extends(ElementsArray, _super); + function ElementsArray() { + return _super !== null && _super.apply(this, arguments) || this; + } + return ElementsArray; +}(Array)); +_b = ElementsArray; +(function () { + var superisArray = _super.isArray; + var customIsArray = function (arg) { return superisArray(arg); }; + _b.isArray = customIsArray; +})(); +ElementsArray.isArray(new ElementsArray()); + + +//// [a.d.ts] +declare class Thing { +} +declare class ElementsArray extends Array { + constructor(arrayLength?: number); + constructor(arrayLength: number); + constructor(...items: any[]); +} diff --git a/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.symbols b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.symbols new file mode 100644 index 00000000000..51d648a9ed7 --- /dev/null +++ b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.symbols @@ -0,0 +1,49 @@ +=== /src/a.js === +class Thing { +>Thing : Symbol(Thing, Decl(a.js, 0, 0)) + + static { + this.doSomething = () => {}; +>this.doSomething : Symbol(Thing.doSomething, Decl(a.js, 1, 12)) +>this : Symbol(Thing, Decl(a.js, 0, 0)) +>doSomething : Symbol(Thing.doSomething, Decl(a.js, 1, 12)) + } +} + +Thing.doSomething(); +>Thing.doSomething : Symbol(Thing.doSomething, Decl(a.js, 1, 12)) +>Thing : Symbol(Thing, Decl(a.js, 0, 0)) +>doSomething : Symbol(Thing.doSomething, Decl(a.js, 1, 12)) + +// GH#46468 +class ElementsArray extends Array { +>ElementsArray : Symbol(ElementsArray, Decl(a.js, 6, 20)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + static { + const superisArray = super.isArray; +>superisArray : Symbol(superisArray, Decl(a.js, 11, 13)) +>super.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) +>super : Symbol(ArrayConstructor, Decl(lib.es5.d.ts, --, --)) +>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) + + const customIsArray = (arg)=> superisArray(arg); +>customIsArray : Symbol(customIsArray, Decl(a.js, 12, 13)) +>arg : Symbol(arg, Decl(a.js, 12, 31)) +>superisArray : Symbol(superisArray, Decl(a.js, 11, 13)) +>arg : Symbol(arg, Decl(a.js, 12, 31)) + + this.isArray = customIsArray; +>this.isArray : Symbol(ElementsArray.isArray, Decl(a.js, 12, 56)) +>this : Symbol(ElementsArray, Decl(a.js, 6, 20)) +>isArray : Symbol(ElementsArray.isArray, Decl(a.js, 12, 56)) +>customIsArray : Symbol(customIsArray, Decl(a.js, 12, 13)) + } +} + +ElementsArray.isArray(new ElementsArray()); +>ElementsArray.isArray : Symbol(ElementsArray.isArray, Decl(a.js, 12, 56)) +>ElementsArray : Symbol(ElementsArray, Decl(a.js, 6, 20)) +>isArray : Symbol(ElementsArray.isArray, Decl(a.js, 12, 56)) +>ElementsArray : Symbol(ElementsArray, Decl(a.js, 6, 20)) + diff --git a/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.types b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.types new file mode 100644 index 00000000000..bbb41f4ea47 --- /dev/null +++ b/tests/baselines/reference/javascriptThisAssignmentInStaticBlock.types @@ -0,0 +1,57 @@ +=== /src/a.js === +class Thing { +>Thing : Thing + + static { + this.doSomething = () => {}; +>this.doSomething = () => {} : () => void +>this.doSomething : () => void +>this : typeof Thing +>doSomething : () => void +>() => {} : () => void + } +} + +Thing.doSomething(); +>Thing.doSomething() : void +>Thing.doSomething : () => void +>Thing : typeof Thing +>doSomething : () => void + +// GH#46468 +class ElementsArray extends Array { +>ElementsArray : ElementsArray +>Array : any[] + + static { + const superisArray = super.isArray; +>superisArray : (arg: any) => arg is any[] +>super.isArray : (arg: any) => arg is any[] +>super : ArrayConstructor +>isArray : (arg: any) => arg is any[] + + const customIsArray = (arg)=> superisArray(arg); +>customIsArray : (arg: any) => boolean +>(arg)=> superisArray(arg) : (arg: any) => boolean +>arg : any +>superisArray(arg) : boolean +>superisArray : (arg: any) => arg is any[] +>arg : any + + this.isArray = customIsArray; +>this.isArray = customIsArray : (arg: any) => boolean +>this.isArray : (arg: any) => boolean +>this : typeof ElementsArray +>isArray : (arg: any) => boolean +>customIsArray : (arg: any) => boolean + } +} + +ElementsArray.isArray(new ElementsArray()); +>ElementsArray.isArray(new ElementsArray()) : boolean +>ElementsArray.isArray : (arg: any) => boolean +>ElementsArray : typeof ElementsArray +>isArray : (arg: any) => boolean +>new ElementsArray() : ElementsArray +>ElementsArray : typeof ElementsArray + diff --git a/tests/cases/compiler/javascriptThisAssignmentInStaticBlock.ts b/tests/cases/compiler/javascriptThisAssignmentInStaticBlock.ts new file mode 100644 index 00000000000..f86508dc986 --- /dev/null +++ b/tests/cases/compiler/javascriptThisAssignmentInStaticBlock.ts @@ -0,0 +1,24 @@ +// @allowJs: true +// @checkJs: true +// @declaration: true +// @outDir: /out/ +// @filename: /src/a.js + +class Thing { + static { + this.doSomething = () => {}; + } +} + +Thing.doSomething(); + +// GH#46468 +class ElementsArray extends Array { + static { + const superisArray = super.isArray; + const customIsArray = (arg)=> superisArray(arg); + this.isArray = customIsArray; + } +} + +ElementsArray.isArray(new ElementsArray()); \ No newline at end of file