🔐 TypeScript — Access Modifiers: Control Visibility and Encapsulation
🧲 Introduction – What Are Access Modifiers in TypeScript?
In TypeScript, access modifiers are keywords used to control the visibility and accessibility of class members (properties and methods). They help enforce encapsulation, a core principle of object-oriented programming (OOP), ensuring that internal implementation details are protected from unintended access or modification.
🎯 In this guide, you’ll learn:
- What access modifiers are and how they work
- The differences between
public,private, andprotected - How to use access modifiers in classes
- Real-world use cases and best practices
🛡️ Why Use Access Modifiers?
Access modifiers allow you to:
- Restrict or expose class members
- Prevent accidental changes to internal logic
- Make class APIs cleaner and more secure
- Enable inheritance and controlled overrides
🔓 public Modifier – Default and Fully Accessible
The public modifier makes a class member accessible from anywhere—inside the class, subclasses, and even from outside the class.
✅ Example:
class User {
public name: string;
constructor(name: string) {
this.name = name;
}
public greet(): void {
console.log(`Hello, ${this.name}`);
}
}
const user = new User("Alice");
user.greet(); // Accessible
console.log(user.name); // Accessible
✅ Note: Members are public by default if no modifier is specified.
🔒 private Modifier – Fully Restricted to the Class
The private modifier makes a member accessible only within the class where it is declared. Subclasses and external code cannot access it.
✅ Example:
class BankAccount {
private balance: number;
constructor(initialBalance: number) {
this.balance = initialBalance;
}
public getBalance(): number {
return this.balance;
}
}
const account = new BankAccount(1000);
// console.log(account.balance); // ❌ Error: 'balance' is private
console.log(account.getBalance()); // ✅ Allowed via public method
🧬 protected Modifier – Accessible in Class and Subclasses
The protected modifier allows access within the class and any subclasses, but not from outside.
✅ Example:
class Animal {
protected sound: string = "Generic sound";
makeSound(): void {
console.log(this.sound);
}
}
class Dog extends Animal {
bark(): void {
this.sound = "Woof!";
this.makeSound();
}
}
const dog = new Dog();
// console.log(dog.sound); // ❌ Error: 'sound' is protected
dog.bark(); // ✅ Outputs: Woof!
🧠 Summary of Access Levels
| Modifier | Class Itself | Subclasses | Outside Access |
|---|---|---|---|
public | ✅ Yes | ✅ Yes | ✅ Yes |
private | ✅ Yes | ❌ No | ❌ No |
protected | ✅ Yes | ✅ Yes | ❌ No |
🧩 Access Modifiers with Constructor Parameters
TypeScript allows you to declare and initialize properties directly in the constructor with access modifiers.
✅ Example:
class Customer {
constructor(private id: number, public name: string) {}
getId(): number {
return this.id;
}
}
const customer = new Customer(101, "John");
// console.log(customer.id); // ❌ Error
console.log(customer.name); // ✅ public
console.log(customer.getId()); // ✅ via public method
✅ Benefits: Less boilerplate, clean and readable code.
🔁 Access Modifiers in Inheritance
Access modifiers are crucial in OOP design where base classes expose only what subclasses need.
class Vehicle {
protected speed: number = 0;
protected accelerate(amount: number): void {
this.speed += amount;
}
}
class Car extends Vehicle {
drive(): void {
this.accelerate(50);
console.log(`Driving at ${this.speed} km/h`);
}
}
const car = new Car();
car.drive();
// car.accelerate(10); // ❌ Error: protected method
💡 Best Practices for Access Modifiers
| ✅ Do | ❌ Avoid |
|---|---|
Use private for sensitive or internal logic | Exposing everything as public |
Use protected for extensible base class logic | Overriding private members in subclasses |
Use public for clearly documented class APIs | Creating subclasses with full internal access |
⚠️ Common Mistakes & How to Avoid Them
| ❌ Mistake | ✅ Fix / Explanation |
|---|---|
Using private when protected is needed | Use protected if subclasses need access |
| Forgetting access modifier in constructor | Specify modifier (public, private, or protected) |
Modifying private from outside | Use public getter/setter methods to expose needed behavior |
| Treating TypeScript modifiers as runtime | Remember: modifiers exist only at compile time |
📌 Summary – Recap & Next Steps
Access modifiers in TypeScript help you enforce encapsulation, create clear APIs, and protect internal logic. Whether you’re building libraries, components, or complex class hierarchies, choosing the right access level is key to writing secure and maintainable code.
🔍 Key Takeaways:
public: Accessible everywhere (default)private: Accessible only within the classprotected: Accessible within the class and subclasses- Use modifiers to improve clarity and control in your codebase
⚙️ Real-world relevance: Access modifiers are crucial in object-oriented design, data protection, inheritance modeling, and modular TypeScript apps.
❓ FAQs – Access Modifiers in TypeScript
❓ Are access modifiers enforced at runtime?
❌ No. They are enforced only at compile time and removed in the transpiled JavaScript.
❓ Can I use access modifiers outside of classes?
❌ No. private, protected, and public apply to class members only.
❓ What’s the difference between private and protected?
📌 private restricts access to the same class, while protected allows access in subclasses too.
❓ Are constructors affected by access modifiers?
✅ Yes. You can declare constructors as public, private, or protected to control instantiation.
❓ Should I always use access modifiers?
✅ Yes. Being explicit improves code readability and maintainability.
Share Now :
