DEV Community

Cover image for Access Modifiers in TypeScript: The Gatekeepers
Nahidul Fahim
Nahidul Fahim

Posted on

Access Modifiers in TypeScript: The Gatekeepers

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

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:

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
Enter fullscreen mode Exit fullscreen mode

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:

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'.
Enter fullscreen mode Exit fullscreen mode

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:

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.
Enter fullscreen mode Exit fullscreen mode

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:

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'.
Enter fullscreen mode Exit fullscreen mode

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

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 Portfolio

Top comments (0)