You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Typescript 3.8.3 : Sharp notation for private method must be alloweded #37677
i think their is not private method in your example. try to write #greet() to replace greet() method in your example, and you have this error message : "A method cannot be named with a private identifier.(18022)".
Reacted by Jesús Leganés-Combarro, Jeremy Black, inker, Wojciech Gebczyk, Jimmy Wärting, Sachin Hegde, Hayden, Mark LeMerise and Dmitrii
Private properties and methods should not be accessible from outside the class instance.
Own methods of a class should have access to private methods of a class if they are static or not.
Can be a constructor private? If it's not, is this singleton example valid?
#instance is a private and static field inside S class and getInstance is static too. As you can create this kind of static fields and methods in NodeJS, it should work in TS
It was a misunderstanding. I thought that your problem was the 'inaccessibility' of the private field #instance from the not private method getInstance(). I agree that there should be no problem.
Anyway. That's the point to use this pattern? Anyone can instantiate this class with new operator. How can I prevent this or it should be a convention in a team not to use new operator with this class?
That's a good point. I think we can use a private constructor. I think It fits well with this pattern. But, in a singleton pattern everyone can use getInstance method or new. If getInstance method exists, then should be used
I'm also unable to use private getters and setters in a class in TS.
classGSExample{
#a: number=0;geta(){// this is filereturnthis.#a;}seta(value: number){// this is filethis.#a =value;}get #b(){// Error: An accessor cannot be named with a private identifier.(18023)returnthis.a*2;}set #b(value: number){// Error: An accessor cannot be named with a private identifier.(18023)this.a=value/2;}}
Also, the workaround leads to the class having field initializers.
While this is not a bad thing per se, it adds an extra constraint on constructor code: If a class has field initializers, its constructor must call super() as the first statement. If there are no field initializers, the only limitation for statements before the super constructor call is that they may not use this, which is less restrictive.
One more annoying thing with the workaround: Forward references do not work.
It should be possible to initialize a private field with a call to a private method. But since with the workaround, TypeScript treats the #private method like a field with an initializer, this only works if the private method is declared before the field using it.
Works in ECMAScript:
class Test {
#myField = this.#init(3);
#init(x) { return x + 1; }
}
Error ("Property '#init' is used before its declaration") when trying to represent this with the workaround in TypeScript, and also a run-time error in ECMAScript when trying to instantiate that class ("TypeError: Cannot read private member #init from an object whose class did not declare it"):
class Test {
#myField = this.#init(3);
#init = (x) => { return x + 1; }
}
This means you are forced to define helper methods before fields, which might not be one's favorite code style.
Considering all the downsides, in our project, we switched back to (clumsy) symbols / "soft" private members. But we are still eagerly waiting for TypeScript to support #private members and would immediately adapt our code!
Is there any reason why it is not allowed to use private methods in Typescript?
Good question. Especially when you use TSC only for type checking and do the actual compilation with Babel, apart from the error message TS18022, everything seems to work fine.
I just give the approach a go to use ts-ignore when declaring #private methods. Ugly, but still better than Symbols. All code just using such methods works fine and is correctly type-checked without any ts-ignore.
Could we probably please have a compiler flag to suppress TS18022?
Reacted by Frank Wienberg, Lauren Yim, Wojciech Gebczyk, flasheye12, André Posso, André Abreu, Eren ÇAY, regnaio, Christopher Addison, Artem and 3 more
Could we probably please have a compiler flag to suppress TS18022?
That doesn't make any sense... This is a spec compliance issue and should just be fixed.
Of course I would prefer a fix, too!
I just guess it is much more effort to implement code generation for that feature, and we only need the type checking part. So for the time being, we use ts-ignore as a workaround, so my real issue with that workaround is that it is still not possible to ignore a specific error.
Is this issue being addressed in the current roadmap? If not, has this issue been triaged at least?
Please give us an update of some sorts.
Thanks
Reacted by Frank Wienberg, Andres Rodriguez, Jeremy Black, Tiago Almeida, Alexandre Villeneuve, Tomáš Polomský, Håkon Ellingsen, Tomas Chmelevskij, Frits Talbot, Daniel and 4 more
Pls fix this soon, I don't use typescript but a ts linter and babel ts compilation and it sucks to have red lines everywhere while my code runs perfectly fine.
Activity
orta commentedon Mar 29, 2020
It is supported: https://www.typescriptlang.org/play/?ts=3.8.0-beta&e=70#example/private-class-fields
Binau commentedon Mar 29, 2020
i think their is not private method in your example. try to write #greet() to replace greet() method in your example, and you have this error message : "A method cannot be named with a private identifier.(18022)".
orta commentedon Mar 29, 2020
True yeah, and I can't seem to find another issue about this 👍
Jamesernator commentedon Mar 30, 2020
The relevant proposal for private methods is here: https://github.com/tc39/proposal-private-methods
Private methods are only shipping in XS so far, but they are in active development in V8.
Binau commentedon Apr 4, 2020
In the same way, static private attribute in class must be allowed too.
however :
do :
Référence : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_fields#Private_fields
proposal : https://github.com/tc39/proposal-static-class-features
Already compatible in edge (79), node (13), chrome
davidbayo10 commentedon Apr 21, 2020
This is a problem...
How can I perform this?
Thank you a lot in advance
mellonis commentedon Apr 21, 2020
Private properties and methods should not be accessible from outside the class instance.
Own methods of a class should have access to private methods of a class if they are static or not.
Can be a constructor private? If it's not, is this singleton example valid?
davidbayo10 commentedon Apr 22, 2020
#instanceis a private and static field insideSclass andgetInstanceis static too. As you can create this kind of static fields and methods in NodeJS, it should work in TShttps://node.green/#ESNEXT-candidate--stage-3--static-class-fields-private-static-class-fields
Node allow this way for creating singleton patterns. Try out yourself. I don't understand why TS is showing that error.
mellonis commentedon Apr 22, 2020
It was a misunderstanding. I thought that your problem was the 'inaccessibility' of the private field
#instancefrom the not private methodgetInstance(). I agree that there should be no problem.Anyway. That's the point to use this pattern? Anyone can instantiate this class with
newoperator. How can I prevent this or it should be a convention in a team not to usenewoperator with this class?davidbayo10 commentedon Apr 22, 2020
That's a good point. I think we can use a private constructor. I think It fits well with this pattern. But, in a singleton pattern everyone can use getInstance method or new. If getInstance method exists, then should be used
mellonis commentedon Apr 22, 2020
I'm also unable to use private getters and setters in a class in TS.
10 remaining items
fwienber commentedon Aug 18, 2020
Yes, but I guess it leads to
#isEmptybeing assigned to each instance instead of being assigned to the class prototype like other methods.kitsonk commentedon Sep 25, 2020
Orta Therox (@orta) is it really in discussion? It is a spec compliance issue now.
fwienber commentedon Oct 22, 2020
Also, the workaround leads to the class having field initializers.
While this is not a bad thing per se, it adds an extra constraint on constructor code: If a class has field initializers, its constructor must call
super()as the first statement. If there are no field initializers, the only limitation for statements before the super constructor call is that they may not usethis, which is less restrictive.fwienber commentedon Nov 12, 2020
One more annoying thing with the workaround: Forward references do not work.
It should be possible to initialize a private field with a call to a private method. But since with the workaround, TypeScript treats the #private method like a field with an initializer, this only works if the private method is declared before the field using it.
Works in ECMAScript:
Error ("Property '#init' is used before its declaration") when trying to represent this with the workaround in TypeScript, and also a run-time error in ECMAScript when trying to instantiate that class ("TypeError: Cannot read private member #init from an object whose class did not declare it"):
This means you are forced to define helper methods before fields, which might not be one's favorite code style.
Considering all the downsides, in our project, we switched back to (clumsy) symbols / "soft" private members. But we are still eagerly waiting for TypeScript to support #private members and would immediately adapt our code!
SerkanSipahi commentedon Nov 14, 2020
Is there any reason why it is not allowed to use private methods in Typescript?
fwienber commentedon Nov 18, 2020
Good question. Especially when you use TSC only for type checking and do the actual compilation with Babel, apart from the error message TS18022, everything seems to work fine.
I just give the approach a go to use ts-ignore when declaring #private methods. Ugly, but still better than Symbols. All code just using such methods works fine and is correctly type-checked without any ts-ignore.
Could we probably please have a compiler flag to suppress TS18022?
kitsonk commentedon Nov 21, 2020
That doesn't make any sense... This is a spec compliance issue and should just be fixed.
ryall commentedon Nov 26, 2020
Yet another issue is setting private identifiers via a class constructor:
TS playground example of above
fwienber commentedon Nov 26, 2020
Of course I would prefer a fix, too!
I just guess it is much more effort to implement code generation for that feature, and we only need the type checking part. So for the time being, we use ts-ignore as a workaround, so my real issue with that workaround is that it is still not possible to ignore a specific error.
stagefright5 commentedon Nov 28, 2020
Is this issue being addressed in the current roadmap? If not, has this issue been triaged at least?
Please give us an update of some sorts.
Thanks
fwienber commentedon Jan 14, 2021
Good news here: #39066 (comment)
danieltroger commentedon Jan 26, 2021
Pls fix this soon, I don't use typescript but a ts linter and babel ts compilation and it sucks to have red lines everywhere while my code runs perfectly fine.
mahnunchik commentedon May 21, 2021
I'm looking forward to fix, it's horrible microsoft/vscode#106351
RyanCavanaugh commentedon May 21, 2021
Implemented in #42458