Introduction to TypeScript Classes- Access Modifiers
Tags: typescript, webdev, programming, javascript
Published: 2021-01-23 20:03:36

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

Classes in TypeScript, like JavaScript are a special syntax for its prototypical inheritance model that is a comparable inheritance in class-based object oriented languages. Classes are just special functions added to ES6 that are meant to mimic the `class` keyword from these other languages. In JavaScript, we can have `class` declarations and `class` expressions, because they are just functions. So like all other functions, there are function declarations and function expressions. This is the same with TypeScript. Classes serve as templates to create new objects. TypeScript extends the syntax of classes of JavaScript and then add its own twists to it. In this article, we’ll look at how to define TypeScript classes and how they inherit from each other. In this article, we’ll look at the access modifiers for class members in TypeScript.

Public, private, and protected modifiers
========================================

Public
------

In TypeScript, class member can have access modifiers added to them. This lets us control the access of the members of class by different parts of the program outside of the class that the members are defined in. The default access modifier for class members in TypeScript is `public` . This means that class member that have no access modifiers will be designated as public members. For example, we can use the `public` modifier like in the following code:

```
class Person {  
  public name: string;  
  public constructor(name: string) {  
    this.name = name;  
  } 

  public getName(): string{  
    return this.name;  
  }  
}

const person = new Person('Jane');  
console.log(person.getName());  
console.log(person.name);
```

In the example above, we designated all the members in our `Person` class as `public` so that we can access them outside the `Person` class. We can call the `getName` method on the `Person` instance and also we can get the `name` field directly from outside the class. The `public` access modifier on the `constructor` method is extra because `constructor` should always be public so we can instantiate the class with it.

Private and Protected
---------------------

When a member of a class is marked as `private` , then it can’t be accessed outside of its containing class. Protected members are only available from within sub-classes of the class that has the protected member and the class that has the member and is marked with the keyword `protected`. For example, if we have a `private` member in our class in like the following code:

```
class Person {  
  private name: string;  
  constructor(name: string) {  
    this.name = name;  
  } 

  public getName(): string{  
    return this.name;  
  }  
}

const person = new Person('Jane');  
console.log(person.getName());  
console.log(person.name);
```

Then we get an error when we try to access it like we did with the member `name` in the `Person` class that we have above. If we try to compile and run the code above, the TypeScript compiler will not compile the code and gives the error message “Property ‘name’ is private and only accessible within class ‘Person’.(2341)“ like we expect for private members.

TypeScript compares type by their structure for public members. If the 2 types have the same public members listed, then they’re marked as being compatible by TypeScript. However, for private and protected members, this isn’t the case. For private and protected members, for 2 classes to be considered equal, then both classes must have the same private and protected members from the same origin for them to be considered to be the same type. For example, if we have the following code:

```
class Person {  
  private name: string;  
  constructor(name: string) {  
    this.name = name;  
  }  
}

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

const human: Human = new Person('Jane');
```

Then we would get the error “ Type ‘Person’ is not assignable to type ‘Human’. Types have separate declarations of a private property ‘name’.(2322)“. This means that because both the `Person` and `Human` have the same private member called `name` , that they can’t be considered the same type, so we can’t assign an instance of `Person` to a variable that’s of type `Human` . This is the same for protected members, so if we have the following code:

```
class Person {  
  protected name: string;  
  constructor(name: string) {  
    this.name = name;  
  }  
}

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

const human: Human = new Person('Jane');
```

We would get the same error. But if we change `protected` to `public` like we do in the code below, then it would work:

```
class Person {  
  public name: string;  
  constructor(name: string) {  
    this.name = name;  
  }  
}

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

const human: Human = new Person('Jane');  
console.log(human.name);
```

If we run the code above, we’ll see ‘Jane’ logged from the `console.log` statement on the last line.

If we have private members in our classes, then they must be in the super-class for both classes for both classes to be considered equal. For example, we can write the following code to make the `Person` and `Human` class to be considered the same while having a common private member `name` for each class:

```
class Animal {  
  private name: string;  
  constructor(name: string) {  
    this.name = name;        
  }  
}

class Person extends Animal{  
  constructor(name: string) {  
    super(name);      
  }  
}

class Human extends Animal{  
  constructor(name: string) {  
    super(name);      
  }  
}

const human: Human = new Person('Jane');  
console.log(human);
```

In the code above, we have the `Animal` class that the private `name` member, and both the `Person` and `Human` classes extends the `Animal` class, so that the `Human` and `Person` will be considered equal since they don’t have separate implementations of the private member `name` , but rather, a common `name` member in the `Animal` class instead which they both inherit from. When we run `console.log` on `human` in the last line, we would see the `Person` object being logged.

Likewise, for protected members, we can do the something similar like in the following code:

```
class Animal {  
  protected name: string;  
  constructor(name: string) {  
    this.name = name;        
  }  
}

class Person extends Animal{  
  constructor(name: string) {  
    super(name);      
  } 

  getName() {  
    return this.name;  
  }  
}

class Human extends Animal{  
  constructor(name: string) {  
    super(name);      
  } 

  getName() {  
    return this.name;  
  }  
}

const human: Human = new Person('Jane');  
console.log(human.getName());
```

In the code above, we have the protected member `name` which can be accessed by its sub-classes `Human` and `Person` , so we can return the value of the `name` member with a `getName` method on each class and the value of the `name` member in the `Animal` class. We need this method because protected members are only available from within sub-classes of the class that has the protected member and the class that has the member. If we run the code above, we would get ‘Jane’ from the `console.log` output from the last line of the code above.

In TypeScript, class members can have access modifiers applied to them. Public is the default access modifier for members if nothing is specified. 2 class are considered equal if they both have the same public members, or that they inherit protected and private members from the same source and have the same public members.