Skip to content

Typescript 3.8.3 : Sharp notation for private method must be alloweded #37677

Description

@Binau

Search Terms

TS18022, sharp

Suggestion

Sharp notation for private method must be alloweded : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_fields#Private_instance_methods

Use Cases

class Test {
#test() {}
}

Examples

class Test {
#test() {}
}
=> TS18022: A method cannot be named with a private identifier.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Activity

  1. orta commented on Mar 29, 2020

    @orta
    Contributor
  2. Binau commented on Mar 29, 2020

    @Binau
    Author

    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)".

  3. orta commented on Mar 29, 2020

    @orta
    Contributor

    True yeah, and I can't seem to find another issue about this 👍

  4. Jamesernator commented on Mar 30, 2020

    @Jamesernator

    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.

  5. Binau commented on Apr 4, 2020

    @Binau
    Author

    In the same way, static private attribute in class must be allowed too.
    however :

    class Test {
    static #TEST:any;
    }
    

    do :

    TS18019: 'static' modifier cannot be used with a private identifier

    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

  6. davidbayo10 commented on Apr 21, 2020

    @davidbayo10

    In the same way, static private attribute in class must be allowed too.
    however :

    class Test {
    static #TEST:any;
    }
    

    do :

    TS18019: 'static' modifier cannot be used with a private identifier

    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

    This is a problem...

    class S {
    
      static #instance: S;
    
      static getInstance(): S {
        if (!this.#instance) {
          this.#instance = new S();
        }
    
        return this.#instance;
      }
    
    }

    How can I perform this?

    Thank you a lot in advance

  7. mellonis commented on Apr 21, 2020

    @mellonis

    In the same way, static private attribute in class must be allowed too.
    however :

    class Test {
    static #TEST:any;
    }
    

    do :

    TS18019: 'static' modifier cannot be used with a private identifier

    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

    This is a problem...

    class S {
    
      static #instance: S;
    
      static getInstance(): S {
        if (!this.#instance) {
          this.#instance = new S();
        }
    
        return this.#instance;
      }
    
    }

    How can I perform this?

    Thank you a lot in advance

    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?

  8. davidbayo10 commented on Apr 22, 2020

    @davidbayo10

    #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

    https://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.

  9. mellonis commented on Apr 22, 2020

    @mellonis

    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?

  10. davidbayo10 commented on Apr 22, 2020

    @davidbayo10

    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

  11. mellonis commented on Apr 22, 2020

    @mellonis

    I'm also unable to use private getters and setters in a class in TS.

    class GSExample {
        #a: number = 0;
    
        get a() { // this is file
            return this.#a;
        }
    
        set a(value: number) { // this is file
            this.#a = value;
        }
    
        get #b() { // Error: An accessor cannot be named with a private identifier.(18023)
            return this.a * 2;
        }
    
        set #b(value: number) { // Error: An accessor cannot be named with a private identifier.(18023)
            this.a = value / 2;
        }
    }
  12. 10 remaining items

  13. fwienber commented on Aug 18, 2020

    @fwienber

    Yes, but I guess it leads to #isEmpty being assigned to each instance instead of being assigned to the class prototype like other methods.

  14. kitsonk commented on Sep 25, 2020

    @kitsonk
    Contributor

    Orta Therox (@orta) is it really in discussion? It is a spec compliance issue now.

  15. fwienber commented on Oct 22, 2020

    @fwienber

    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.

  16. fwienber commented on Nov 12, 2020

    @fwienber

    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!

  17. SerkanSipahi commented on Nov 14, 2020

    @SerkanSipahi

    Is there any reason why it is not allowed to use private methods in Typescript?

  18. fwienber commented on Nov 18, 2020

    @fwienber

    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?

  19. kitsonk commented on Nov 21, 2020

    @kitsonk
    Contributor

    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.

  20. ryall commented on Nov 26, 2020

    @ryall

    Yet another issue is setting private identifiers via a class constructor:

    class Testing {
      constructor(private #test: string) {} // ERROR: Private identifiers cannot be used as parameters
    }

    TS playground example of above

  21. fwienber commented on Nov 26, 2020

    @fwienber

    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.

  22. stagefright5 commented on Nov 28, 2020

    @stagefright5

    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

  23. fwienber commented on Jan 14, 2021

    @fwienber

    Good news here: #39066 (comment)

  24. danieltroger commented on Jan 26, 2021

    @danieltroger

    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.

  25. mahnunchik commented on May 21, 2021

    @mahnunchik

    I'm looking forward to fix, it's horrible microsoft/vscode#106351

  26. RyanCavanaugh commented on May 21, 2021

    @RyanCavanaugh
    Member

    Implemented in #42458

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions