Class Getter and Setter in TypeScript: A Complete Guide

Updated: January 8, 2024 By: Guest Contributor Post a comment

Introduction

Understanding getters and setters in TypeScript is key for building encapsulated and maintainable classes. This guide demystifies these concepts with clear examples.

Basics of Getters and Setters

Getters and setters are special methods that provide read and write access to an object’s properties. They’re known as ‘accessors’ and ‘mutators’, respectively. In TypeScript, they are implemented with the get and set keywords.

class User {
  private _email: string = '';

  public get email(): string {
    return this._email;
  }

  public set email(value: string) {
    if (value.indexOf('@') === -1) {
      throw new Error('Invalid email');
    }
    this._email = value;
  }
}

The User class has a private property _email that is accessed through the publicly exposed getters and setters.

Advantages of Using Accessors

They offer control over how a property is accessed and modified, potentially validating or transforming the data before assigning it.

Using Getters and Setters in Interfaces

Accessors can be specified in TypeScript interfaces to enforce their implementation in classes.

interface IUser {
  get email(): string;
  set email(value: string): void;
}

class User implements IUser {
  // implementation goes here
}

Accessor Signatures in Abstract Classes

Abstract classes can declare accessor signatures, to be implemented in derived classes.

abstract class AbstractUser {
  abstract get email(): string;
  abstract set email(value: string): void;
}

class User extends AbstractUser {
  // implementation goes here
}

Getters and Setters with Computed Properties

Computed properties can be used in conjunction with getters and setters for dynamic property values.

class User {
  private firstName: string;
  private lastName: string;

  public get fullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }

  public set fullName(value: string) {
    [this.firstName, this.lastName] = value.split(' ');
  }
}

Readonly Accessors

Sometimes you may want to provide a readonly property accessor.

class User {
  private password: string;

  public get password(): string {
    throw new Error('Password is write-only');
  }

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

Advanced Patterns: Using Getters and Setters for Lazy Loading

Accessors can be utilized for lazy initialization patterns, deferring the creation of computationally expensive objects.

class UserProfile {
  private _details?: Details;

  public get details(): Details {
    if (!this._details) {
      this._details = this.loadDetails();
    }
    return this._details;
  }
}

Best Practices

Best practices you should follow when using TypeScript with class getters and setters:

  • Keep accessor methods lightweight.
  • Avoid side effects in getters.
  • Use accessors to enforce invariants.
  • Accessors should not mirror the exact structure of the underlying data.

Conclusion

Getters and setters in TypeScript add a layer of abstraction to properties, allowing control over access and assignment. Mastering their usage can lead to more robust and adaptable code architectures.