In TypeScript, accessors (getters and setters) are special methods that enable precise and controlled access and modification of class member variables. Using accessors enhances encapsulation, hides internal implementation details, and allows executing additional logic when retrieving or setting property values, such as validation or data transformation.
Basic Usage
In TypeScript, getters and setters are defined as special methods within a class. Getters retrieve property values, while setters set property values. Here is a simple example:
typescriptclass Person { private _name: string; constructor(name: string) { this._name = name; } // Getter get name(): string { return this._name; } // Setter set name(value: string) { if (value.length > 0) { this._name = value; } else { console.log("Invalid name."); } } } let person = new Person("Alice"); console.log(person.name); // Output: Alice person.name = "Bob"; console.log(person.name); // Output: Bob person.name = ""; // Attempt to set an invalid name
In this example, we have a Person class with a private member _name. We control access to _name using getters and setters, and implement simple validation logic when setting new values.
Use Cases
- Data Validation: Perform checks before setting property values to ensure data validity and consistency.
- Data Transformation: Apply transformations between user input and data, such as date formatting or numerical conversion.
- Triggering Events or Side Effects: Trigger additional logic when setting property values, such as updating a database or sending notifications.
Advanced Applications
In complex scenarios, getters and setters can integrate with other TypeScript features like static properties, inheritance, and interfaces to build robust and extensible applications. For example, we can create an Employee class extending Person to extend its functionality:
typescriptclass Employee extends Person { private _salary: number; constructor(name: string, salary: number) { super(name); this._salary = salary; } get salary(): number { return this._salary; } set salary(newSalary: number) { if (newSalary >= 0) { this._salary = newSalary; } else { console.log("Invalid salary amount."); } } } let employee = new Employee("Charlie", 5000); console.log(employee.name); // Output: Charlie console.log(employee.salary); // Output: 5000 employee.salary = 6000; console.log(employee.salary); // Output: 6000 employee.salary = -100; // Attempt to set an invalid salary
This example demonstrates using accessors in subclasses while maintaining the encapsulation and interface of the parent class. These techniques help developers write safer, more maintainable, and extensible code.