TypeScript Accessors & Mutators (Getters & Setters) Tutorial

In this TypeScript tutorial we learn how to encapsulate a class and hide its implementation details, forcing developers to access the class through getters and setters.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

What are accessors & mutators

Accessors and mutators allow us to hide implementation details from an instance object.

As an example, consider a class that validates a user’s email address. The class would encapsulate the inner workings of checking for symbols, valid domains, sending confirmation emails etc.

We don’t need to worry about how it does that behind the scenes, all we want to do is instantiate the class, send it an email address to evaluate and receive done or not done feedback.

Encapsulation has the added benefit of providing us with some data protection.

Note: We should compile the following scripts with the compiler flag –target es6 or greater.

Accessor Method (Getter)

Let’s consider a simple example where we want the full name of a person.

Example:
class Person {

  firstName;
  lastName;

  constructor(fn:string, ln:string) {

    this.firstName = fn;
    this.lastName = ln;
  }
}

var p1 = new Person("John", "Doe");
console.log(p1.firstName + " " + p1.lastName);

In the example above, we combine the first and last names when we want to print it to the console.

We can use a getter method to get the first and last names and combine them.

To write a get method, we write the keyword get in front of the method name.

Syntax:
// getter definition
get method_name() {
  // body
}

// getter call
object_name.method_name;

When we invoke the getter method, we don’t include the open and close parentheses as we would with a regular function.

Example:
class Person {

  firstName;
  lastName;

  constructor(fn:string, ln:string) {

    this.firstName = fn;
    this.lastName = ln;
  }

  get fullName() {

    return this.firstName + " " + this.lastName;
  }
}

var p1 = new Person("John", "Doe");
console.log(p1.fullName);

We could achieve the same result with a normal method.

Example:
class Person {

  firstName;
  lastName;

  constructor(fn:string, ln:string) {

    this.firstName = fn;
    this.lastName = ln;
  }

  fullName() {

    return this.firstName + " " + this.lastName;
  }
}

var p1 = new Person("John", "Doe");
console.log( p1.fullName() );

The method in the example above does the exact same thing as the getter method. However, the getter method has slightly simpler syntax and it’s easier to recognize the purpose of the getter method at a glance.

Another benefit is that our data is protected. In this case we won’t be able to change the name, we can only get the values.

Example:
class Person {

  firstName;
  lastName;

  constructor(fn:string, ln:string) {

    this.firstName = fn;
    this.lastName = ln;
  }

  get fullName() {

    return this.firstName + " " + this.lastName;
  }
}

var p1 = new Person("John", "Doe");

// attempt to mutate class properties
p1.fullName = "John Wick";

console.log(p1.fullName);

In the example above, we try to change the name, but it doesn’t work and the compiler raise an error.

Output:
main.ts:21:4 - error TS2540: Cannot assign to 'fullName' because it is a read-only property.

21 p1.fullName = "John Wick";
      ~~~~~~~~

Mutator Method (Setter)

A setter method is used to mutate the value of a class member.

In our previous example, there was no way for us to change a person’s name other than instantiating a new object.

This provides us with class safety, but what if a person gets married and we need to change their last name.

TypeScript allows us to change the value of a property by using a setter method.

To write a setter method we use the set keyword in front of the method name.

Set methods only allow a single parameter, which is used to change the value of the property.

Syntax:
set method_name(parameter) {

  this.property = parameter;
}
Example:
class Person {

  firstName;
  lastName;

  constructor(fn:string, ln:string) {

    this.firstName = fn;
    this.lastName = ln;
  }

  get fullName() {

    return this.firstName + " " + this.lastName;
  }

  set setLastName(newLastName) {

    this.lastName = newLastName;
  }
}

var p1 = new Person("John", "Doe");

// mutate class property
p1.setLastName = "Porter";

console.log(p1.fullName);

In the example above, we maintain class safety because the setter method will only change the last name, it can’t change anything else.

Summary: Points to remember

  • Accessor and Mutator methods encapsulate our classes, keeping them safe by hiding unnecessary implementation details and only modifying certain values.
  • Get and Set methods have a slightly simpler syntax and also allow us to recognize their purpose at a glance.
  • To access a value, we use a get method.
  • To mutate a value, we use a set method.
    • A set method may only contain a single parameter.