Access modifiers
TypeScript supports several access modifiers that let you control the visibility of properties and methods in classes. They exist for encapsulation, to restrict access to an object's internal data.
Main access modifiers
| Modifier | Where it's visible | Keyword |
|---|---|---|
| public | Everywhere (default) | public |
| private | Only within the same class | private |
| protected | Within the class and its subclasses | protected |
| readonly | Read-only, cannot be changed after initialization | readonly (not exactly about access, but often used together) |
1. public: public access (the default)
All class members are public by default,
even if the modifier is not written.
class User {
public name: string; // you can omit public - it's the default
constructor(name: string) {
this.name = name;
}
public greet() {
console.log(`Hello, ${this.name}`);
}
}
const u = new User("Tim");
u.name = "Alex"; // accessible from outside
u.greet(); // can be calledpublic means: the property or method is accessible everywhere,
inside the class, in subclasses, and outside the class.
2. private: private fields and methods
private makes a property or method inaccessible outside the class,
even to subclasses.
class Account {
private balance: number = 0;
deposit(amount: number) {
this.balance += amount;
}
getBalance() {
return this.balance;
}
}
const acc = new Account();
acc.deposit(1000); // OK
acc.getBalance(); // OK
acc.balance = 9999; // Error: private propertyPrivate members are visible only inside the class itself. Even subclasses have no access to them.
A modern alternative: #private (JS-level private)
Since 2022, real privacy at the JS level (ESNext) is supported:
class Account {
#balance = 0; // private at the JS level
deposit(amount: number) {
this.#balance += amount;
}
}Unlike private (TS-only),
#balance is genuinely inaccessible even via Reflect/Proxy at runtime.
TypeScript supports both variants.
3. protected: protected access
protected means the property is accessible:
- inside the class itself,
- and in all its subclasses,
- but not from outside.
class Animal {
protected move() {
console.log("Moving...");
}
}
class Dog extends Animal {
bark() {
this.move(); // accessible in the subclass
console.log("Woof!");
}
}
const d = new Dog();
d.bark(); // OK
d.move(); // Error: protected
protectedis a "slightly more openprivate" that is accessible only along the inheritance chain.
4. readonly: read-only
readonly does not restrict the scope of visibility,
but it forbids changing the value after initialization (in the constructor or right at declaration):
class Point {
readonly x: number;
readonly y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
const p = new Point(5, 10);
p.x = 20; // Error: read-only propertyOften combined with public, private, protected:
class User {
constructor(public readonly id: number, public name: string) {}
}5. Modifiers on constructor parameters (shorthand)
TypeScript lets you declare and initialize properties right in the constructor's parameters:
class User {
constructor(
public name: string,
private password: string,
protected readonly role: string
) {}
}
const u = new User("Tim", "123", "admin");
u.name; // OK
u.password; // Error: private
u.role; // Error: protectedIn JS this is just a constructor, but TS creates and types the fields automatically.
6. Combining modifiers
| Example | What it means |
|---|---|
public readonly | Accessible everywhere, but cannot be changed |
private readonly | Only inside the class, and cannot be changed |
protected readonly | Only in the class and subclasses, cannot be changed |
class Config {
protected readonly env = "prod";
private readonly secret = "123";
}7. Modifiers on methods and accessors
Modifiers can also be placed before methods / get / set:
class Example {
private value = 0;
protected get double() {
return this.value * 2;
}
public setValue(v: number) {
this.value = v;
}
}SUMMARY TABLE
| Modifier | Visibility | Access in subclasses | Access from outside | Notes |
|---|---|---|---|---|
| public | Everywhere | Yes | Yes | Default |
| private | Only in the class | No | No | TS-only, removed at compile time |
| protected | In the class and subclasses | Yes | No | Used with inheritance |
| readonly | Everywhere (depends on public/protected/private) | Yes | Yes/No | Read-only |
| #private (ESNext) | Only in the class | No | No | Genuinely private at runtime |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.