TypeScript classes provide a powerful way to structure your code using object-oriented programming principles. In this comprehensive guide, we'll explore everything you need to know about TypeScript class properties, from basic syntax to advanced features.
Class properties are essential building blocks that help you create well-organized and maintainable code. Whether you're new to TypeScript or looking to deepen your understanding, this guide will walk you through all the important concepts.
Understanding Class Properties in TypeScript
Class properties, also known as class fields, are variables that belong to a class. They store data that is specific to class instances or shared among all instances. Let's start with the basics:
// Basic class property declaration
class User {
name: string; // Instance property
static version = '1.0'; // Static property
constructor(userName: string) {
this.name = userName;
}
}
// Creating an instance
const user = new User('John');
console.log(user.name); // Output: John
console.log(User.version); // Output: 1.0
Code language: JavaScript (javascript)
Access Modifiers
TypeScript provides three access modifiers to control property visibility:
class Employee {
public name: string; // Accessible from anywhere
private salary: number; // Only accessible within the class
protected id: number; // Accessible within class and subclasses
constructor(name: string, salary: number, id: number) {
this.name = name;
this.salary = salary;
this.id = id;
}
}
Code language: JavaScript (javascript)
Property Initialization
TypeScript offers several ways to initialize class properties:
1. Constructor Initialization
class Product {
name: string;
price: number;
constructor(name: string, price: number) {
this.name = name;
this.price = price;
}
}
Code language: JavaScript (javascript)
2. Parameter Properties
// Shorthand syntax using parameter properties
class Product {
constructor(
public name: string,
public price: number
) {}
}
// Both approaches create the same structure
const product = new Product('Laptop', 999);
console.log(product.name); // Output: Laptop
Code language: JavaScript (javascript)
Optional and Readonly Properties
TypeScript allows you to define optional and readonly properties:
class Configuration {
readonly apiKey: string; // Can't be modified after initialization
optional?: string; // Optional property
constructor(key: string) {
this.apiKey = key;
}
}
const config = new Configuration('abc123');
// config.apiKey = 'xyz'; // Error: Cannot assign to 'apiKey' because it is a read-only property
Code language: JavaScript (javascript)
Getter and Setter Methods
TypeScript supports getter and setter methods for more controlled property access:
class Account {
private _balance: number = 0;
// Getter method
get balance(): number {
return this._balance;
}
// Setter method with validation
set balance(value: number) {
if (value < 0) {
throw new Error('Balance cannot be negative');
}
this._balance = value;
}
}
const account = new Account();
account.balance = 100; // Uses setter
console.log(account.balance); // Uses getter, Output: 100
Code language: JavaScript (javascript)
Best Practices for Class Properties
- Initialize Properties
Always initialize properties or declare them in the constructor to avoid undefined values:
class BestPractice {
// Initialize with default value
count: number = 0;
// Or use the definite assignment assertion
name!: string;
// Or initialize in constructor
constructor() {
this.name = 'Default';
}
}
Code language: JavaScript (javascript)
- Use Access Modifiers
Explicitly declare access modifiers to make code intention clear:
class Employee {
private id: number;
public name: string;
protected department: string;
constructor(id: number, name: string, dept: string) {
this.id = id;
this.name = name;
this.department = dept;
}
}
Code language: JavaScript (javascript)
- Implement Proper Encapsulation
Use private properties with getter/setter methods when you need to control access:
class UserAccount {
private _email: string;
get email(): string {
return this._email;
}
set email(value: string) {
if (!value.includes('@')) {
throw new Error('Invalid email format');
}
this._email = value;
}
}
Code language: JavaScript (javascript)
Common Pitfalls and Solutions
1. Forgetting to Initialize Properties
// Bad practice
class Example {
property: string; // Property 'property' has no initializer
}
// Good practice
class Example {
property: string = 'default';
// OR
constructor() {
this.property = 'default';
}
}
Code language: JavaScript (javascript)
2. Incorrect Access Modifier Usage
// Bad practice - exposing internal state
class User {
public password: string; // Sensitive data should not be public
}
// Good practice
class User {
private password: string;
constructor(password: string) {
this.password = password;
}
validatePassword(input: string): boolean {
return this.password === input;
}
}
Code language: JavaScript (javascript)
Conclusion
Mastering TypeScript class properties is crucial for writing maintainable object-oriented code. By following the best practices and understanding the various features available, you can create robust and type-safe applications.
Remember to:
- Always initialize properties
- Use appropriate access modifiers
- Implement proper encapsulation
- Leverage TypeScript's type system
Now you're ready to build better TypeScript applications using class properties effectively. Happy coding!