This error occurs after vSCode is updated.
code example:
views/view.model.ts
export class View$Model {
get closestModelView(this: View): View {
return this.closest(x => x.isModel == true || x.isTemplate);
}
get closestModel(this: View): Model {
var view = this.closestModelView;
if (view) {
return view.model;
}
return null;
}
}
view.ts
///<reference path='views/view.model.ts'/>
export class View extends ViewParse.Plug.BaseControl{ ... }
export interface View {
on(name:'click',fn:(view:View)=>void)
....
}
export interface View extends View$Model { }
Util.inherit(View, View$Model)
tsconfig.json
{
"compilerOptions": {
"outFile": "../ts/view.js",
"declaration": true,
"target": "es6",
"removeComments": true,
"sourceMap": true
}
}
current typescript version:3.9.5
current @types/node version:14.0.14
current vscode version:1.45.1

the "this: View" Will report an error, prompt: 'get' and 'set' accessors cannot declare 'this' parameters.
I know what this error message means, but it's always been written like this.
Has Typescript tweaked its rules?
I don't want to change the code. I don't like code that is too long for a single file, and I have a lot of code to change.This pattern simulates partial classes.
I want to know what to do about it, the reduced version, the special quote statement, or what?
I have checked the sample question, but no one mentioned it。
This happens every time you compile, which is bad. To seek help
A 'get' accessor cannot have parameters. (1054)
How should another this then be bound to a property at all?
export interface View extends View$Model { }
The get property and the method inside the View$Model declare "this:View"
This has been used in previous versions, but the recent update of VSCode has caused this problem.
the View class inherits View$Model, so View$Model actually can't pull the View Class, but at this point the View declares export Interface which is global, so there's nothing wrong with declare this:View in View$Model.In fact, the method inside the View$Model used this:View without any problems, just 'get' and 'set' accessors report prompt: 'get' and 'set' accessors cannot declare 'this' parameters.
OK, I think it can be done: https://stackoverflow.com/questions/37973290/javascript-bind-method-does-not-work-on-getter-property#answer-37973399
I'm not involved here, but I think a playground link might be helpful.
This was incorrectly allowed and never actually worked. See #36883
Thank you for your help, @WhileTrueEndWhile , @RyanCavanaugh 。
I see the problem, but my one is different from this one。
I declare the inheritance of the class
export interface View extends View$Model { }
That alone, of course, would not work in practice in JavaScript
So let's add a little bit of code like this
Util.inherit(View, View$Model)
The source code for this method looks like this
inherit(Mix, ...mixins) {
return using.classExtend.apply(using, arguments);
},
classExtend(Mix, ...mixins) {
function copyProperties(target, source) {
for (let key of Reflect.ownKeys(source)) {
if (key !== "constructor"
&& key !== "prototype"
&& key !== "name"
) {
let desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}
}
}
for (let mixin of mixins) {
copyProperties(Mix, mixin);
copyProperties(Mix.prototype, mixin.prototype);
}
return Mix;
}
It's been written like this for a couple of years, and it works without any problems,
It was the latest update to VSCode that reported these errors
The "this" statement in the parameter should check inheritance, but I declare inheritance。The #36883 doesn't。
I think people who purposely write 'this' know exactly what they're doing. 36883 people don't understand Typescript and JS very well, but get it wrong.
I'm going to simulate partial classes.Write a class as multiple files.Because the code is too long for a single file, it's not particularly maintainable.
If not, how do partial classes express themselves?
@RyanCavanaugh How do you do this if you emulate partial classes, current Typescript versions?
In the current version, the "get" and "Set" Accessors "simulation doesn't seem to work.
This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.
This change also broke something that I sometimes do with TypesScript & JS prototype - something like "extension methods"
Playground
declare global {
interface Array<T> extends MyArrayExtension<T> {}
}
@extention(Array)
export abstract class MyArrayExtension<T> {
get myLength(this: Array<T>) {
return this.length;
}
}
function extention(clz: any) {
return function (target: any) {
// iterate 'target' methods, getters, setters - and add them to 'clz.prototype'
}
}
@rgbui
I see the problem, but my one is different from this one。
Not it isn't, nothing is stopping a user from doing new View$Model().closestModelView having it type check and getting a runtime error. @kobiburnley is a lot safer by labeling the class as abstract so someone would need to subclass it then instantiate which is much less likely to do accidentally, but still the point is that typescript can't validate the this parameter on accessors in the same way as methods so letting you do it leads to a false sense of security.
I think people who purposely write 'this' know exactly what they're doing.
You could make this argument for pretty much everything, if we just assume the user knows what they are doing at all times then why typescript at all? You know this isn't the case because your next statement contradicts it:
36883 people don't understand Typescript and JS very well, but get it wrong.
As the person who raised that ticket I do take personal offence to this, I very clearly outline my actual use case in my second comment, I was very well aware that I was using this correctly and the runtime behaviour was correct.
I'm going to simulate partial classes.Write a class as multiple files.Because the code is too long for a single file, it's not particularly maintainable.
If not, how do partial classes express themselves?
@RyanCavanaugh How do you do this if you emulate partial classes, current Typescript versions?
In the current version, the "get" and "Set" Accessors "simulation doesn't seem to work.
Normally when there are definitions in your class that are implemented in a way you can't express to typescript, you create an interface to merge with the class, in your case this would cause cyclical references so to break it I would recommend Picking the properties that you actually use, something like this:
// pick only the fields of View that this extension relies on.
export interface View$Model extends Pick<View, "closest"> {}
export abstract class View$Model { // added abstract to ensure people don't instantiate this directly by mistake.
get closestModelView(): View {
return this.closest(x => x.isModel == true || x.isTemplate);
}
get closestModel(): Model | null {
const view = this.closestModelView;
if (view) {
return view.model;
}
return null;
}
}
This has an added benefit that you end up documenting the dependencies between your partial class parts at the cost that intellisense won't suggest fields that aren't already mentioned in the Pick.
Another option that may be more applicable for @kobiburnley's case is to just use good old fashioned this as Type if there are relatively few places it is needed:
@extension(Array)
export abstract class MyArrayExtension<T> {
get myLength() {
return (this as unknown as Array<T>).length;
}
}
This has the benefit that if something does go wrong the as unknown as Type sticks out as something that is probably the root issue at the cost of being noisy.