Private, Public & Protected Access Modifiers in TypeScript


Access modifiers are essential because they allow us to enforce encapsulation and define the boundaries of class member accessibility. With access modifiers, we can restrict access to certain members, ensuring they are only accessible within the class itself. We can also make members public, allowing them to be accessed from anywhere in our codebase. Furthermore, protected members enable access within the class and its derived classes.

In this tutorial, we will explore the private, public, and protected access modifiers in TypeScript.

Syntax

Users can follow the syntax below to apply access modifiers to class members in TypeScript −

class ClassName {
   private propertyName: type;
   public methodName(): returnType {
      // Method body
   }
   protected anotherPropertyName: type;
}

In the above syntax −

  • private − This access modifier restricts the access of the member to the class where it is declared. The keyword is private denotes it.

  • public − This access modifier allows unrestricted access to the member from anywhere. It is the default access modifier if none is specified. The keyword public denotes it.

  • protected − This access modifier allows access to the member within the class and its derived classes. It is denoted by the keyword protected.

Example 1: Public Access Modifier

In this example, we created a Person class with a public property name, which can be accessed and modified anywhere in the code. We also have a public method greet(), that prints a greeting message using the name property.

We then create an instance of the Person class named Person. We can directly access the name property of the person object and assign it a value. Finally, we call the greet() method on the person object, which outputs the greeting message, including the name. Users can observe the output to see the greeting message with the provided name.

class Person {
   public name: string = "";

   public greet(): void {
      console.log(`Hello, my name is ${this.name}!`);
   }
} 
// Creating an instance of the Person class
const person = new Person(); 

// Assigning a value to the public property
person.name = "John"; 

// Calling the public method to display the greeting
person.greet();

On compiling, it will generate the following JavaScript code −

var Person = /** @class */ (function () {
   function Person() {
      this.name = "";
   }
   Person.prototype.greet = function () {
      console.log("Hello, my name is ".concat(this.name, "!"));
   };
   return Person;
}());
// Creating an instance of the Person class
var person = new Person();

// Assigning a value to the public property
person.name = "John";

// Calling the public method to display the greeting
person.greet();

Output

The above code will produce the following output −

Hello, my name is John!

Example 2: Private Access Modifier

In this example, we have created a BankAccount class with a private property balance, which can only be accessed and modified within the class. Additionally, we have a private method calculateInterest(), that calculates the interest based on the balance.

After defining the class, we create an instance of the BankAccount class named account with an initial balance of $1000.

However, attempting to directly access the private property balance or call the private method calculateInterest() from outside the class will result in an error, as these members are inaccessible outside of the class scope.

Users can observe in the output that attempting to access the private members will result in a TypeError.

class BankAccount {
   private balance: number; 
   constructor(initialBalance: number) {
      this.balance = initialBalance;
   } 
   private calculateInterest(): number {
      const interestRate = 0.05;
      return this.balance * interestRate;
   } 
}  
// Creating an instance of the BankAccount class
const account = new BankAccount(1000); 

// Attempting to access private members
console.log(account.balance); 
console.log(account.calculateInterest()); 

On compiling, it will generate the following JavaScript code −

var BankAccount = /** @class */ (function () {
   function BankAccount(initialBalance) {
      this.balance = initialBalance;
   }
   BankAccount.prototype.calculateInterest = function () {
      var interestRate = 0.05;
      return this.balance * interestRate;
   };
   return BankAccount;
}());
// Creating an instance of the BankAccount class
var account = new BankAccount(1000);

// Attempting to access private members
console.log(account.balance);
console.log(account.calculateInterest());

And it will give the following error −

Property 'balance' is private and only accessible within class 'BankAccount'.
Property 'calculateInterest' is private and only accessible within class 'BankAccount'.

Output

The above JavaScript code will produce the following output −

1000
50

Example 3: Protected Access Modifier

In this example, we create a base class Animal with a protected property name, which can be accessed and modified within the class and its derived classes. We also have a protected method makeSound(), that simply logs a message.

We then create a derived class Dog that extends the Animal class. The Dog class adds a public method bark(), which utilizes the name property inherited from the base class to output a bark message.

Finally, we create an instance of the Dog class named dog with the name "Buddy" and call the bark() method.

The output will show the dog's name followed by the bark message.

class Animal {
   protected name: string; 
   constructor(name: string) {
      this.name = name;
   } 
   protected makeSound(): void {
      console.log("The animal makes a sound");
   }
} 
class Dog extends Animal {
   public bark(): void {
      console.log(`${this.name} barks!`);
   }
} 
// Creating an instance of the Dog class
const dog = new Dog("Buddy"); 
dog.bark();

On compiling, it will generate the following JavaScript code −

var __extends = (this && this.__extends) || (function () {
   var extendStatics = function (d, b) {
      extendStatics = Object.setPrototypeOf ||
         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
         function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
      return extendStatics(d, b);
    };
    return function (d, b) {
      if (typeof b !== "function" && b !== null)
         throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
      extendStatics(d, b);
      function __() { this.constructor = d; }
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
   };
})();
var Animal = /** @class */ (function () {
   function Animal(name) {
      this.name = name;
   }
   Animal.prototype.makeSound = function () {
      console.log("The animal makes a sound");
   };
   return Animal;
}());
var Dog = /** @class */ (function (_super) {
   __extends(Dog, _super);
   function Dog() {
      return _super !== null && _super.apply(this, arguments) || this;
   }
   Dog.prototype.bark = function () {
      console.log("".concat(this.name, " barks!"));
   };
   return Dog;
}(Animal));
// Creating an instance of the Dog class
var dog = new Dog("Buddy");
dog.bark();

Output

On compiling, the above code will generate a JavaScript code. The JavaScript code will produce the following result −

Buddy barks!

In this tutorial, we learned about the private, public, and protected access modifiers in TypeScript. Private members are only accessible within the class, public members are accessible from anywhere, and protected members are accessible within the class and its derived classes. By using these access modifiers, we can control the visibility and accessibility of class members based on our needs.

Updated on: 21-Aug-2023

184 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements