Table of Contents
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.