Encapsulation in TypeScript
Tags: typescript, javascript, ts, webdev
Published: 2022-04-21 23:33:29

**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.

```TypeScript
let numberOfPeople: number = 7;
```

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

```TypeScript
let albert: Personne = undefined;
```

## Class declaration in typescript

The basic class definition in TS is like the following.

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

```TypeScript
let joe: Person = new Person();
```
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.

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

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

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.

```TypeScript
export class User {
    password: string;

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

    setPassword(password: string): void {
        this.password = password;
    }
}
```
Then we can refactor it to something more interesting.

```TypeScript
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`;
    }   
}
```

**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.

```TypeScript
let robert: User = new User('Robert');
console.log(robert.password); // => Robert
console.log(robert._password); // Works but should throw exception
```
Let me show you what I got as response.


![After running the code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7dwm4nr5hzh2ume2lmxo.png)

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.

```TypeScript
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`;
    }
}
```
If you run the test code back again, you will get the following output.


![Bad access detected](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yrchj0mj98vco6e63sz6.png)

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!