Access Modifiers in TypeScript: The Gatekeepers
Tags: typescript, webdev, programming, learning
Published: 2024-06-12 04:24:37

Access modifiers in TypeScript are essential tools for managing the accessibility of class members (properties and methods) within our code. By controlling who can access and modify these members, access modifiers help us implement encapsulation, a core principle of object-oriented programming. We can use class members within their own class, from anywhere outside the class, or within any child or derived class.

Access modifiers in TypeScript act as gatekeepers, controlling the visibility and accessibility of class members. They prevent invalid usage and maintain data integrity. If not explicitly set, TypeScript automatically assigns the public modifier, making all members accessible from anywhere.

TypeScript provides three primary access modifiers: `public`, `private`, and `protected`. Let's explore each one in detail.


![Access modifiers in TypeScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/evu44ggl8t5yoafodgmp.jpg)

## 1. Public
The `public` modifier is the default access level in TypeScript. When a class member is marked as `public`, it means that the member can be accessed from anywhere: inside the class, outside the class, or even in subclasses. If we do not specify an access modifier, the member is implicitly `public`.

**Example:**

```typescript
class Animal {
    public name: string;

    constructor(name: string) {
        this.name = name;
    }

    public move(distance: number): void {
        console.log(`${this.name} moved ${distance} meters.`);
    }
}

const dog = new Animal('Dog');
dog.move(10); // Accessible
console.log(dog.name); // Accessible
```
In the example above, both the `name` property and the `move` method are `public`, allowing unrestricted access.

## 2. Private
The `private` modifier restricts access to the member only within the class it is defined. This means that private members cannot be accessed or modified from outside the class, including in derived classes.

**Example:**

```typescript
class Animal {
    private name: string;

    constructor(name: string) {
        this.name = name;
    }

    public move(distance: number): void {
        console.log(`${this.name} moved ${distance} meters.`);
    }
}

const cat = new Animal('Cat');
cat.move(5); // Accessible
// console.log(cat.name); // Error: Property 'name' is private and only accessible within class 'Animal'.
```
Here, the `name` property is private, so attempting to access `cat.name` from outside the class results in an error.

## 3. Protected
The `protected` modifier allows access to the member within the class it is defined and in any subclass derived from it. However, it still restricts access from outside these classes.

**Example:**

```typescript
class Animal {
    protected name: string;

    constructor(name: string) {
        this.name = name;
    }

    protected move(distance: number): void {
        console.log(`${this.name} moved ${distance} meters.`);
    }
}

class Bird extends Animal {
    public fly(distance: number): void {
        console.log(`${this.name} is flying.`);
        this.move(distance); // Accessible
    }
}

const eagle = new Bird('Eagle');
eagle.fly(20); // Accessible
// eagle.move(20); // Error: Property 'move' is protected and only accessible within class 'Animal' and its subclasses.
```
In this example, the `name` property and the `move` method are `protected`, allowing the `Bird` class to access them. However, trying to call `move` on an instance of `Bird` from outside the class hierarchy results in an error.

## Combining Access Modifiers with Constructors
TypeScript allows us to declare and initialize properties directly in the constructor, using access modifiers.

**Example:**

```typescript
class Person {
    constructor(public name: string, private age: number) {}

    public getAge(): number {
        return this.age;
    }
}

const john = new Person('John', 30);
console.log(john.name); // Accessible
console.log(john.getAge()); // Accessible
// console.log(john.age); // Error: Property 'age' is private and only accessible within class 'Person'.
```
In this case, `name` is public, so it can be accessed freely, while `age` is private, restricting access to within the class.

## Why Use Access Modifiers?
- **Encapsulation:** By using access modifiers, we can hide the internal implementation details of a class from the outside world, exposing only what is necessary.
- **Maintainability:** Properly encapsulated code is easier to understand and maintain because it clearly defines the boundaries of what can and cannot be accessed.
- **Flexibility:** Encapsulation allows us to change the internal implementation without affecting external code, as long as the public interface remains consistent.
- **Error Prevention:** Restricting access to critical parts of our code helps prevent unintended modifications, reducing the risk of bugs.

## Access Modifiers at a Glance
The table below summarizes the accessibility of class members based on their access modifiers:

![Access modifiers in a glance](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3neosr0gg6pfwc1ycj1d.png)

## Conclusion
Access modifiers in TypeScript are a powerful feature that help us write safer, more maintainable code by controlling the visibility of class members. By understanding and using `public`, `private`, and `protected` effectively, we can create well-encapsulated classes that are easier to work with and less prone to errors. Whether we're just starting with TypeScript or looking to refine our skills, mastering access modifiers is a key step in becoming proficient developers.

Follow me on: [LinkedIn](https://www.linkedin.com/in/iamnahidul-islam) [Portfolio](https://nahidul-islam.vercel.app/)