TypeScript provides three main accessibility modifiers to control the visibility of class members (properties and methods):

  1. public
  2. private
  3. protected

1. public: Accessible Everywhere

By default, all members of a class are public. This means they can be accessed from anywhere.

Example 1: Public Members

class Animal {
  public name: string;
 
  public constructor(theName: string) {
    this.name = theName;
  }
 
  public move(distanceInMeters: number) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
  }
}
 
let dog = new Animal("Dog");
console.log(dog.name);   // OK, because 'name' is public
dog.move(10);            // OK, because 'move' is public
  • public allows the property or method to be accessed from anywhere.

2. private: Accessible Only Within the Class

A private member can only be accessed within the class where it’s defined. It cannot be accessed from outside or from derived classes.

Example 2: Private Members

class Animal {
  private name: string;
 
  constructor(theName: string) {
    this.name = theName;
  }
}
 
new Animal("Cat").name;  // Error: 'name' is private and cannot be accessed
  • private prevents external access to the member. Trying to access name directly from outside results in an error.

3. protected: Accessible Within the Class and Its Subclasses

A protected member can be accessed within the class where it’s defined and by instances of classes that inherit from it (subclasses).

Example 3: Protected Members

class Person {
  protected name: string;
 
  constructor(name: string) {
    this.name = name;
  }
}
 
class Employee extends Person {
  private department: string;
 
  constructor(name: string, department: string) {
    super(name);
    this.department = department;
  }
 
  public getElevatorPitch() {
    return `Hello, my name is ${this.name} and I work in ${this.department}.`;
  }
}
 
let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());  // OK, 'name' is accessible in Employee
console.log(howard.name);               // Error: 'name' is protected, not accessible outside Employee
  • protected allows access in the class and its subclasses, but not from outside.

4. Inheritance with Access Modifiers

Inheritance works with these access modifiers:

  • private members are not inherited and cannot be accessed from derived classes.
  • protected members can be inherited and accessed within the derived class.

Example 4: Inheritance with private and protected

class Animal {
  private name: string;
 
  constructor(theName: string) {
    this.name = theName;
  }
}
 
class Rhino extends Animal {
  constructor() {
    super("Rhino");
  }
}
 
let animal = new Animal("Goat");
let rhino = new Rhino();
 
animal = rhino;  // OK: Animal and Rhino are compatible, but 'name' is private in Animal
  • You cannot assign animal = employee because Animal and Employee are not compatible types due to the private name property in Animal.

5. Access Modifiers in Constructors

Constructors can also have access modifiers to control how class properties are initialized and whether they can be accessed outside the class.

Example 5: Constructor with protected

class Person {
  protected name: string;
 
  protected constructor(theName: string) {
    this.name = theName;
  }
}
 
class Employee extends Person {
  private department: string;
 
  constructor(name: string, department: string) {
    super(name);
    this.department = department;
  }
 
  public getElevatorPitch() {
    return `Hello, my name is ${this.name} and I work in ${this.department}.`;
  }
}
  • The constructor of Person is protected, so it cannot be called directly outside of the class but can be accessed in subclasses like Employee.

Key Points:

  1. public members can be accessed from anywhere.
  2. private members are only accessible within the class and cannot be accessed by derived classes.
  3. protected members can be accessed within the class and its subclasses.
  4. Constructors can also be marked with public, private, or protected to control how they can be called.