-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Cannot Optionalize Class Getters #14417
Comments
A class is an implementation of a type. if you want to declare an optional property i suggest adding an interface interface Person {
firstName: string;
lastName: string;
readonly fullName?;
} |
Thanks! I'm aware that that's a possibility. I suppose I just don't understand why the language would disallow marking getters as optional when everything else on a class can be marked as optional. It seems inconsistent. Is there a good reason for this inconsistency? Forgive me if I misunderstand, but the "A class is an implementation of a type" reasoning seems more like a how-the-compiler-is-implemented reason as opposed to a how-the-language-should-work reason. I'm interested in the later. |
Accessors (getters/setters) are just properties. you can declare methods and properties as option. but you can not have an implementation to an optional property or a method. |
Maybe I misunderstand. You can specify an implementation to an optional class method:
There are no errors with that. |
@mhegazy Like bradenhs said, class methods can be made optional, as shown in this merged PR: #8625
As can be seen, it's an optional method that also has a body/implementation specified. That's the same thing we'd like for class getters/setters, like so:
However, this doesn't compile currently, which seems inconsistent when class methods work with it fine. |
@mhegazy seems inconsistent to allow (bodied) optional methods but not getters. Thoughts? |
If this suggestion is accepted would you guys take a PR for it? (I don't know much about the TypeScript code base but this doesn't seem like it would be a complicated task). |
@ahejlsberg I saw that you implemented the ability to optionalize class properties in #8625. Is there a specific reason the ability to optionalize getters was omitted from that PR? |
Accepting PRs to allow this with similar semantics as optional methods. |
I think I'll take a stab at this. It would allow for some better patterns in the state management library I'm creating for my CS498R class (nearly graduated!) |
Finally had some time to go ahead and implement this. Take a look at the PR here #16344. |
Any updates on this? Can we get the PR merged? |
@jahtalab It's been a while and I need to update the PR. I'm taking a couple "hobby programming" days off from work this next month so I may get to it then. |
To anyone who is skimming through this conversation and wonders why last comment was as much time ago as 29. Jan: the more up-to-date conversation (up to 26 days ago) is on #16344 |
Related to this issue, I wish to propose that setters allow optional arguments, as it seems inconsistent when compared to regular methods, e.g. class C {
setX(n?: number) {} // Allowed.
set x(n?: number) {} // Not allowed: "A 'set' accessor cannot have an optional parameter."
} The main problem being, you cannot allow passing |
I'm not sure @inad9300 's question is actually about #2521. If you think about it for a second, though, it makes sense. The setter is called when an assignment operator is encountered, but a syntactically valid assignment always has exactly one l-value and one r-value, even if that r-value is |
any update? This should be allowed, which is only possible when |
You don't need this to solve your specific use case. You could just declare your class with |
@RyanCavanaugh is there any update on this issue? it has literally been years now. |
I didn't even notice when I made my previous comments that there are actually at least two issues in this ticket. One, can I declare a class whose getters are optional? (I still don't understand the actual use case here -- if you don't @xtianus79 are you trying to get an update on "issue one"? If so, the linked PR #16344 has some back-and-forth but looks like it needs some extra discussion before it gets resolved. |
@thw0rted use case could be to not have to use them in call signatures eg when using classes as interfaces |
I hadn't thought about the "classes as interfaces" thing because I don't actually do that myself. Are there particular times when it makes more sense than just writing an explicit interface definition? If you're making methods (and getters) optional entirely so that you can use the class as an interface, wouldn't it mean that reads always need conditional access even though you know that, for actual instances of the class, they're always defined? |
Oof. I just ran into this myself. Funny thing is the IDE (PhpStorm) doesn't see For now I did |
would love to see |
Not done since 2017 😵 |
I support this.
|
Seems this a real issue and still not implemented. |
this is so hellish to provide custom api ! My solution is using Implement with interface , but is make thing complicate. class Plugin {_uid:string}
interface IPerson {
plugin?:Partial<Plugin>;
}
class Person implements IPerson {
static create(param:IPerson){return new Person}
private __PluginUUID: string = null;
get Plugin(): Plugin {
return findPlugin(this.__PluginUUID)
}
set Plugin(data: Plugin) {
this.__PluginUUID = data._uid;
}
set plugin(data: Partial<Plugin>) {
this.Plugin = new Plugin(data);
}
}
const foo = Person.create({
plugin:{_uid:''},
}) |
See this comment for details, but modern class field behavior makes optionalizing getters and setters kind of a tricky territory, since checking for their existence is very awkward. While, relationally, we can probably make up rules for working with them, making them useful in control flow and the like seems much harder; given there's very little apparent demand for it and they seem very awkward to use, maybe we'll just continue to not allow them for now - at least until a better way to handle them in control flow and type guarding becomes apparent (because common assignment patterns potentially throwing would be super annoying). |
This feature is sorely needed :/ It's a one-off case that can't even be solved by bypassing this compile error with an option or something. |
Just stumbled into this and I'm super disappointed this functionality doesn't exist... it creates some really JavaScript-y errors if you aren't super intentional about checking your potentially undefined getter values |
TypeScript Version: 2.2.1
Code
Expected behavior:
Since
fullName
is optional the following should work:Actual behavior:
A syntax error occurs on this line
get fullName?() {
I'm not sure if omitting the ability to optionalize getters was by design or not. If it was by design, I'd love to know the reasoning behind it.
The text was updated successfully, but these errors were encountered: