private vs. # in TypeScript

The key difference between these two methods is that the private keyword is enforced only by TypeScript during compilation and does not affect the JavaScript output, which means the privacy is not enforced at runtime. On the other hand, private fields (using #) offer runtime privacy as well, making them inaccessible outside the class even in plain JavaScript. This makes them suitable for more secure data handling where privacy needs to be guaranteed.

class Life {
  private meaning: unknown;
  private story: string[] = [];
  #secrets: any[] = [];

  constructor() {}

  addStory(story: string) {
    if (story.toLocaleLowerCase().includes("love")) {
      this.meaning = "LOVE";
    } else if (story.toLocaleLowerCase().includes("secret")) {
      this.#secrets.push(story);
    } else {
      this.story.push(story);
    }
  }

  get summary() {
    return {
      stories: this.story,
      secrets: this.#secrets,
      meaning: this.meaning,
    };
  }
}

const myLife = new Life();

myLife.addStory("I was born");
myLife.addStory("I have a new secret to tell you");
myLife.addStory("I loved my family");

console.log(myLife.summary);

console.log(myLife.story);
`Property 'story' is private and only accessible within class 'Life'. (2341)`;

console.log(myLife.#secrets);
`Property '#secrets' is not accessible outside class 'Life' because it has a private identifier. (18013)`;