Class Basics
Class Basics
Basic Class Definition
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): string {
return `Hi, I'm ${this.name}, ${this.age} years old.`;
}
}
const alice = new Person('Alice', 30);
console.log(alice.greet());
Parameter Properties (Shorthand)
// Parameter properties auto-create and assign class members
class User {
constructor(
public readonly id: number,
public name: string,
private email: string,
protected role: string = 'user'
) {}
getDisplay(): string {
return `${this.name} (${this.role})`;
}
}
const user = new User(1, 'Alice', 'alice@test.com');
console.log(user.name); // OK
// console.log(user.email); // Error: private
Access Modifiers
| Modifier | Class | Subclass | Outside |
|---|---|---|---|
| public | Yes | Yes | Yes |
| protected | Yes | Yes | No |
| private | Yes | No | No |
| readonly | Yes | Yes (read) | Yes (read) |
Inheritance and Abstract Classes
Inheritance and Abstract Classes
Inheritance
class Animal {
constructor(public name: string) {}
speak(): string {
return `${this.name} makes a sound.`;
}
}
class Dog extends Animal {
constructor(name: string, public breed: string) {
super(name);
}
speak(): string {
return `${this.name} barks!`;
}
}
const rex = new Dog('Rex', 'Labrador');
console.log(rex.speak()); // 'Rex barks!'
console.log(rex.breed); // 'Labrador'
Abstract Classes
abstract class Shape {
abstract area(): number;
abstract perimeter(): number;
describe(): string {
return `Area: ${this.area()}, Perimeter: ${this.perimeter()}`;
}
}
class Circle extends Shape {
constructor(public radius: number) {
super();
}
area(): number {
return Math.PI * this.radius ** 2;
}
perimeter(): number {
return 2 * Math.PI * this.radius;
}
}
// Cannot instantiate abstract class
// const shape = new Shape(); // Error
const circle = new Circle(5);
console.log(circle.describe());
Method Overriding
class Base {
greet(): string {
return 'Hello';
}
}
class Derived extends Base {
override greet(): string {
return 'Hi there';
}
}
// Use override keyword to prevent typos
Static Members
Static Members
Static Properties and Methods
class MathUtils {
static readonly PI = 3.141592653589793;
static add(a: number, b: number): number {
return a + b;
}
static multiply(a: number, b: number): number {
return a * b;
}
}
MathUtils.PI; // 3.141592653589793
MathUtils.add(1, 2); // 3
// Static factory method
class User {
constructor(
public name: string,
public email: string
) {}
static fromJSON(json: string): User {
const data = JSON.parse(json);
return new User(data.name, data.email);
}
}
const user = User.fromJSON('{"name":"Alice","email":"alice@test.com"}');
Static Initialization
class Config {
static instance: Config;
static {
// Static initialization block
Config.instance = new Config();
}
private constructor() {}
}
Enums as Static Collections
enum HttpMethod {
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
DELETE = 'DELETE'
}
class ApiClient {
static async request(method: HttpMethod, url: string): Promise<unknown> {
const response = await fetch(url, { method });
return response.json();
}
}
ApiClient.request(HttpMethod.GET, '/api/users');
Getters and Setters
Getters and Setters
Computed Properties
class Temperature {
private _celsius: number;
constructor(celsius: number) {
this._celsius = celsius;
}
get fahrenheit(): number {
return this._celsius * 9 / 5 + 32;
}
set fahrenheit(value: number) {
this._celsius = (value - 32) * 5 / 9;
}
get celsius(): number {
return this._celsius;
}
set celsius(value: number) {
if (value < -273.15) {
throw new Error('Temperature below absolute zero');
}
this._celsius = value;
}
}
const temp = new Temperature(100);
console.log(temp.fahrenheit); // 212
temp.fahrenheit = 32;
console.log(temp.celsius); // 0
Validation in Setters
class BankAccount {
private _balance: number = 0;
get balance(): number {
return this._balance;
}
set balance(value: number) {
if (value < 0) {
throw new Error('Balance cannot be negative');
}
this._balance = value;
}
deposit(amount: number): void {
this.balance = this._balance + amount;
}
withdraw(amount: number): boolean {
if (amount > this._balance) return false;
this.balance = this._balance - amount;
return true;
}
}