Skip to content
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

Private fields in class declaration expose internal identifier in declarations #56145

Closed
dragomirtitian opened this issue Oct 18, 2023 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@dragomirtitian
Copy link
Contributor

dragomirtitian commented Oct 18, 2023

πŸ”Ž Search Terms

class expressions private fields declaration

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

Playground Link

πŸ’» Code

const x = class {
    #id = 10 // "__#3455@#id": number; in declarations 
}

πŸ™ Actual behavior

The class expression is rendered in declarations as declare const x: { new (): { "__#34@#id": number; }; } exposing the internal identifier of the private field.

πŸ™‚ Expected behavior

Since we can't emit #private in an object type (like for class declarations) and we don't have class types, it's hard to come up with a solution that preserves the nominal nature of the type. I see 3 possible solutions:

  1. Remove the type from the field (at least the internally used type will not end up being exposed) declare const x: { new (): { "__#34@#id": unknown ; }; } (partial fix)
  2. Remove the private fields and lose the nominal nature of the class
  3. Remove the private fields and add a unique symbol that ensures the class behaves nominally (mostly)
declare const x_private: unique symbol;
declare const x: {
    new (): {
        [x_private]: "#private"
    };
}; 

Third option would be the ideal one IMO. There is precedent for adding 'fake' declarations in declaration emit (_default for default exports, Name_Base for classes that use expressions in the heritage clause)

Additional information about the issue

The numeric id is not stable, and can change based on what other private fields are seen before the one emitted in the declaration

class C { #x = 1 } // Comment out this line id is different 
export  const x = class {
    #id = 10 // "__#3455@#id": number; in declarations 
}

Playground Link

(It is even worse in a language service, as the id changes each time you make a change anywhere in the file)

@MartinJohns
Copy link
Contributor

Duplicate of #36548. Used search terms: private emit in:title

@typescript-bot
Copy link
Collaborator

This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants