TS Access Modifiers
TypeScript supports the classic three levels — public, protected, private — plus JavaScript's true-private #fields.
The three TS modifiers
| Modifier | Visible from |
|---|---|
public (default) | Anywhere. |
protected | The class and its subclasses. |
private | The declaring class only. |
Example
TS
class Account {
public owner: string;
protected balance: number;
private secretKey: string;
constructor(owner: string, balance: number) {
this.owner = owner;
this.balance = balance;
this.secretKey = crypto.randomUUID();
}
}
class SavingsAccount extends Account {
bonus() {
this.balance *= 1.01; // ✓ protected — visible to subclass
// this.secretKey; // ✗ private to Account
}
}
TS private vs JS # private
TS
class A {
private tsPrivate = 1; // compile-time only — JS object still has it
#jsPrivate = 2; // true private — not on the JS object
}
const a = new A();
console.log((a as any).tsPrivate); // 1 — escapes via any
// (a as any).#jsPrivate // SyntaxError
TS private is a compile-time check. #fields are enforced by the JS runtime — strictly private even at runtime.
Parameter property shorthand
TS
class Account {
constructor(
public readonly owner: string,
private balance = 0,
) {}
}
Default is public
Omit a modifier and members are public. Most style guides recommend writing it out anyway — explicit beats implicit.
Tip: If you need true-private state for a library boundary, prefer
#private. For internal app classes, TS private is fine and integrates more smoothly with serializers and debuggers.Example
Example
class Account {
public owner: string;
protected balance: number;
private secretKey: string;
constructor(owner: string, balance: number) {
this.owner = owner;
this.balance = balance;
this.secretKey = crypto.randomUUID();
}
}
const a = new Account('Ada', 100);
console.log(a.owner);
Try it Yourself »
Exercise
JS true-private field prefix.
name = 'Ada';
A single character.
Discussion
Loading…