Skip to main content

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

ModifierWhere it's visibleKeyword
publicEverywhere (default)public
privateOnly within the same classprivate
protectedWithin the class and its subclassesprotected
readonlyRead-only, cannot be changed after initializationreadonly (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.

javascript
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 called

public 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.

javascript
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 property

Private 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:

javascript
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.
javascript
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

protected is a "slightly more open private" 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):

javascript
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 property

Often combined with public, private, protected:

javascript
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:

javascript
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: protected

In JS this is just a constructor, but TS creates and types the fields automatically.


6. Combining modifiers

ExampleWhat it means
public readonlyAccessible everywhere, but cannot be changed
private readonlyOnly inside the class, and cannot be changed
protected readonlyOnly in the class and subclasses, cannot be changed
javascript
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:

javascript
class Example { private value = 0; protected get double() { return this.value * 2; } public setValue(v: number) { this.value = v; } }

SUMMARY TABLE

ModifierVisibilityAccess in subclassesAccess from outsideNotes
publicEverywhereYesYesDefault
privateOnly in the classNoNoTS-only, removed at compile time
protectedIn the class and subclassesYesNoUsed with inheritance
readonlyEverywhere (depends on public/protected/private)YesYes/NoRead-only
#private (ESNext)Only in the classNoNoGenuinely private at runtime

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.