-
Notifications
You must be signed in to change notification settings - Fork 12.8k
'get' and 'set' accessors cannot declare 'this' parameters. #39254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
How should another |
export interface View extends View$Model { } 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 |
This was incorrectly allowed and never actually worked. See #36883 |
Thank you for your help, @WhileTrueEndWhile , @RyanCavanaugh 。
It's been written like this for a couple of years, and it works without any problems, The "this" statement in the parameter should check inheritance, but I declare inheritance。The #36883 doesn't。 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. |
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" 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'
}
} |
Not it isn't, nothing is stopping a user from 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:
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
Normally when there are definitions in your class that are implemented in a way you can't express to typescript, you create an // 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 Another option that may be more applicable for @kobiburnley's case is to just use good old fashioned @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 |
Considering this restriction, is that possible to implement a For example, I can make smth like this with a static method: type Constructor = new (...args: any[]) => {}
function Singleton<TBase extends Constructor>(Base: TBase) {
return class Singleton extends Base {
static _i: any
static i<T>(this: (new (...args: any[]) => T)): T {
return (this._i = this._i || new this);
}
}
}
// - - -
class MyClass extends Singleton() {
hello() {
// ...
}
}
MyClass.i().hello() But is there a way to achieve a |
@anatoliyarkhipov this is nearly identical to what I was trying to accomplish in my original use case, the answer is unfortunately no. Having a I believe my exact words were:
I'm not saying it would be fundementally impossible to support, just that the effort to get getters to work seemlessly as properties as it currently does but also be treated as potentially generic functions would be substantial. If the use cases for this kind of design increases maybe it is worth visiting but for now I think it still falls under the "too niche to be worth implementation effort" category of features. |
@tadhgmister Okay, fair enough. I didn't intend to argue, I just wasn't sure if I got it right. Also, one workaround I found, and which I'd call acceptable (to my taste), is to declare the static property on the heir. It feels almost like a configuration property required by the "API" of class MyClass extends Singleton() {
static i: MyClass
hello() {
// ...
}
}
MyClass.i.hello |
Respectfully, @tadhgmister, I think that's incorrect.
type Ctor<T = {}> = new (...args: any[]) => T
function Singleton<T extends Ctor>(Base: T) {
return class Singleton extends Base {
private static readonly _instance: T
static get instance(): T {
return (this._instance = this._instance || new Base())
}
}
}
class MyClass extends Singleton() {
hello() {}
}
MyClass.instance.hello() Having pointed out that it's possible, @anatoliyarkhipov, personally, I fail to understand why you'd want to do that in the first place. As far as I see it, that'd be quite the anti-pattern. Creating generic static properties is definitely a fair use case for mixins, generally. What I don't see at all, is the point of a "Singleton" in JS / TS. The language is full of them already. They're just usually not explicitly called that.
Idiomatic Singleton// begin of file
export class MyClass {
private constructor() {}
static hello() {}
}
// end of file // other file
import { MyClass } from '../path/to/modules-are-singletons'
MyClass.hello() or even bolder architecture: // begin of file
const property = 'I am a private, static property of a singleton'
export function hello() {
console.log(property)
}
// end of file // other file
import { hello } from '../path/to/modules-are-singletons'
hello() Why so complicated? |
@jpilkahn Unfortunately, your example doesn't achieve what I wanted to achieve, unless I'm thoroughly mistaken. What I want for the static getter, is to return an instance of As for why I want to do it this way... well... |
I'm sorry but your the statement If you had a base class then it would instantiate the base class, not the subclass that is desired: class A {
hello = "world"
}
class B extends Singleton(A) {
foo = "bar"
}
console.log(B.instance.hello) // works because it is in the base passed to Singleton
console.log(B.instance.foo) // undefined because you didn't instantiate B, you instantiated A The only way around this is to instead use That said I totally agree with the idea that needing a dynamic getter is kind of overkill, just doing |
Is it planned for typescript to add support for that? Allowing this could be really useful |
not planned unless you can find an issue specifically requesting it, this issue and the root #36883 are both just about whether it is allowed syntactically - no one's opened the discussion for proper support. (as far as I know) If you do want to make a case for support raise a new issue (search for dups first, I haven't) and try to make an argument for use cases that would benefit, probably link to mine here #36883 (comment), as I say there it feels like a niche use-case but maybe there is more substance than I realize. |
This error occurs after vSCode is updated.
code example:
views/view.model.ts
view.ts
tsconfig.json
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
The text was updated successfully, but these errors were encountered: