Encapsulation in TypeScript

trash07

Lonv'ha KPETO

Posted on April 21, 2022

Encapsulation in TypeScript

TypeScript(TS) developers usualy use encapsulation bad. This is due to the fact that they just learned it in the context of building angular, React and even Vue JS like applications. Their focus was not primarily TS but other thing.

This guide is for web developers who wish to understand the basic of property encapsulation in TS. At the end, you will:

  • Know what property encapsulation is;
  • Know non-encapsulation bottlenecks;
  • Hide properties with encapsulation;
  • Enhance class definition with encapsulation.

To be able to follow allong correctly, we suppose you know the following concepts:

  • Classes definition and motivation;
  • Variable declaration;
  • Object oriented concepts like classes, objects, polymorphisms, abstract classes, etc.

What are variables ?

A variable is a memory reservation in order to store values. For the computer to know what calculations it can make on variables, they need to have types. A type is a definition of a set of values and the operations that can be applied to them. For exemple, if we decide to dim a variable as an integer, the implication is that it can be able to store all integer values and they can participate to addition, substraction, mutiplication and many more operations. This makes sens. However, if we decide to dim a variable as a string, it can surely store all kind of texts but what about adding two string? We can say it's concatenation (adding one string at the end of another one). What about subtracting two strings? It is not semantic. So are some operations like multiplication and division.

Langages in the world fall in two categories: typed and untyped. Typed langages enforce you to specifiy the type of a variable at it declaration. This have many benefits:

  • It helps build quality software,
  • It helps detect some compile time issues,
  • It lowers the bug atractivity of a computer program.

TS is a typed language. This means every variable in TS is supposed to have a type. There are some basic types like number, string, boolean. For exemple, the following code declares a variable named numberOfPeople of type number that can receive numbers and participate to all number friendly operations.

let numberOfPeople: number = 7;
Enter fullscreen mode Exit fullscreen mode

Basically, you can declare a variable of any type. It can be basic types or even complex programmer defined types like classes and interfaces.

let albert: Personne = undefined;
Enter fullscreen mode Exit fullscreen mode

Class declaration in typescript

The basic class definition in TS is like the following.

class Person {}
Enter fullscreen mode Exit fullscreen mode

This declares a class (a new type) named Person. With this assert, we can declare variables like what follows.

let joe: Person = new Person();
Enter fullscreen mode Exit fullscreen mode

Classes can have properties and methods as well. They all form the body of a class definition. Properties describe the characteristics of the class. Methods describe the behavior.

class Person {
    name: String; // A characteristic of a person

    run(): String { // A behavior of the Person
       return `${this.name} is running fast.`;
    }
}
Enter fullscreen mode Exit fullscreen mode

Properties and methods in a class can have access modifiers to specify the scope of availability. Access modifiers are tools to realize encapsulation. A private access specifier intends visibility only inside of the class. A public available everywhere and a protected is only available in the class and all it's sub-classes (classes extending a class to add more functionality).

The substance of encapsulation is using access modifiers to restrict unwanted access and protect data from side effects. Let's say we want to design a User class so that it encapsulates a password property. We can come up first with something like the following exemple.

export class User {
    password: string;

    getPassword(): string {
        return this.password;
    }

    setPassword(password: string): void {
        this.password = password;
    }
}
Enter fullscreen mode Exit fullscreen mode

Then we can refactor it to something more interesting.

export class User {
    _password: string;

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

    get password(): string {
        return this._password;
    }

    set password(password: string) {
        this._password = password;
    }

    givePass(): string {
        return `I don't want to do that outside of this class`;
    }   
}
Enter fullscreen mode Exit fullscreen mode

By default in TS, all class properties and methods are public. A huge misconception about that fact is that properties starting with and underscore (_) are private. It is not the case. I think it's just a convention of doing things to start naming private properties with and underscore. Let's prove that by testing the class. Just add the following lines to the previous file.

let robert: User = new User('Robert');
console.log(robert.password); // => Robert
console.log(robert._password); // Works but should throw exception
Enter fullscreen mode Exit fullscreen mode

Let me show you what I got as response.

After running the code

The output shows that I am still able to see and even update the property I thought was encapsulated.

To fix this issue, we need to strictly specify the access modifier.

export class User {
    private _password: string;

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

    get password(): string {
        return this._password;
    }

    set password(password: string) {
        this._password = password;
    }

    givePass(): string {
        return `I don't want to do that outside of this class`;
    }
}
Enter fullscreen mode Exit fullscreen mode

If you run the test code back again, you will get the following output.

Bad access detected

Tada! That's what we are looking for: restricting access to properties and methods so that they are only accessible where we want them for the purpose of protecting data.

Give aways

To strictly encapsulate in TS, you can follow the following steps:

  1. find the way to define the property or method and mark it with the good access modifier (You can use the underscore private variable naming strategy);

  2. provide getters and setters to control the access mecanism of the property if needed;

  3. enjoy seeing encapsulation working for you!

💖 💪 🙅 🚩
trash07
Lonv'ha KPETO

Posted on April 21, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Encapsulation in TypeScript
typescript Encapsulation in TypeScript

April 21, 2022