TypeScript error

TS2341: Using a @private member from outside its class

  • Error TS2341
  • Tested with TypeScript 5.9

error TS2341: Property 'balanceCents' is private and only accessible within class 'Account'. is reported when code outside a class reads or writes a member whose JSDoc says @private. TS2445 is the same for @protected, which also allows subclasses.

These tags are enforced by the checker only. At run time the property is an ordinary public property, which is the difference from JavaScript's own #private fields: those cannot be reached from outside the class at all, and even writing account.#balanceCents outside the class is a syntax error in JavaScript.

At a glance

CodeTS2341
MessageProperty '{0}' is private and only accessible within class '{1}'.
Also on this page: TS2445 Property '{0}' is protected and only accessible within class '{1}' and its subclasses.
TypeScript's categoryerror
Listed underClasses, JSX and unused code
Turned on by No option: every checked file reports it
In .js files Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file

The messages are TypeScript's own text from its diagnostic messages file (Apache-2.0); {0} and {1} are filled in by tsc for each error.

What it looks like

account.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: account.js(18,9): error TS2341: Property 'balanceCents' is private and only accessible within class 'Account'. account.js(20,9): error TS2445: Property 'audit' is protected and only accessible within class 'Account' and its subclasses. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. account.js(18,9): error TS2341: Property 'balanceCents' is private and only accessible within class 'Account'. account.js(20,9): error TS2445: Property 'audit' is protected and only accessible within class 'Account' and its subclasses. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. account.js(18,9): error TS2341: Property 'balanceCents' is private and only accessible within class 'Account'. account.js(20,9): error TS2445: Property 'audit' is protected and only accessible within class 'Account' and its subclasses. checked 21 October 2026
export class Account {
  /** @private */
  balanceCents = 0;

  /** @protected */
  audit() {
    return `balance ${this.balanceCents}`;
  }

  /** @param {number} cents */
  deposit(cents) {
    this.balanceCents += cents;
  }
}

const account = new Account();
account.balanceCents = 1_000_000;error TS2341: Property 'balanceCents' is private and only accessible within class 'Account'.
account.audit();error TS2445: Property 'audit' is protected and only accessible within class 'Account' and its subclasses.
Using @private and @protected members from outside the class.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

What causes it

  • A member is tagged @private or @protected and is used from outside the class (or, for @private, from a subclass).
  • The tag was added to an existing property that other code still uses directly.

How to fix it

Use the class's public methods, or make the field truly private

Change the outside code to call what the class offers (deposit), or add a method or getter for what it needs. If the member must never be touched from outside, #balanceCents enforces that in the running code too, and a getter can expose it read-only.

account.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
export class Account {
  #balanceCents = 0;

  /** @param {number} cents */
  deposit(cents) {
    this.#balanceCents += cents;
  }

  get balanceCents() {
    return this.#balanceCents;
  }
}

const account = new Account();
account.deposit(1999);
console.log(account.balanceCents);
Go through the public methods, or use a real #private field.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Gotchas

  • In a constructor function (not a class), @private on a this.x = ... assignment is reported as TS2341 on that assignment itself, because only a class body counts as inside the class; use a class for private members.
  • TypeScript's private keyword is not allowed in a .js file (TS8009); the tag is its JSDoc spelling.

Sources

Last reviewed 20 October 2026.