TypeScript Static Members

Class-level properties and methods

⚡ What are Static Members?

Static members belong to the class itself rather than instances. They're accessed using the class name and shared across all instances. Perfect for utility functions, counters, or configuration values that don't change per instance.


class MathHelper {
    static PI: number = 3.14159;
    
    static calculateArea(radius: number): number {
        return this.PI * radius * radius;
    }
}
                                    

Static vs Instance Members

📦

Static Properties

Shared across all instances

class Counter {
    static count: number = 0;
    
    static increment() {
        Counter.count++;
    }
}
🔧

Static Methods

Called on class, not instances

class Utils {
    static formatDate(date: Date) {
        return date.toISOString();
    }
}
🎯

Instance Members

Unique to each object

class User {
    name: string;
    
    constructor(name: string) {
        this.name = name;
    }
}

🔹 Static Properties

Static properties are shared across all instances of a class:

class Database {
    static connectionString: string = "localhost:5432";
    static maxConnections: number = 100;
    
    static getConfig(): string {
        return `${this.connectionString} (Max: ${this.maxConnections})`;
    }
}

// Access without creating an instance
console.log(Database.connectionString);  // localhost:5432
console.log(Database.getConfig());       // localhost:5432 (Max: 100)

// Change static property
Database.maxConnections = 200;
console.log(Database.maxConnections);    // 200

Output:

localhost:5432
localhost:5432 (Max: 100)
200

🔹 Static Methods

Static methods can be called without creating an instance:

class Calculator {
    static add(a: number, b: number): number {
        return a + b;
    }
    
    static subtract(a: number, b: number): number {
        return a - b;
    }
    
    static multiply(a: number, b: number): number {
        return a * b;
    }
}

// Call static methods directly on the class
console.log(Calculator.add(5, 3));       // 8
console.log(Calculator.subtract(10, 4)); // 6
console.log(Calculator.multiply(6, 7));  // 42

// No need to create an instance
// const calc = new Calculator(); // Not necessary!

Output:

8
6
42

🔹 Instance Counter Example

Use static properties to track instances across all objects:

class User {
    static totalUsers: number = 0;
    name: string;
    id: number;
    
    constructor(name: string) {
        this.name = name;
        User.totalUsers++;           // Increment static counter
        this.id = User.totalUsers;   // Assign unique ID
    }
    
    static getUserCount(): number {
        return User.totalUsers;
    }
}

const user1 = new User("Alice");
console.log(`User: ${user1.name}, ID: ${user1.id}`);
console.log(`Total users: ${User.getUserCount()}`);

const user2 = new User("Bob");
console.log(`User: ${user2.name}, ID: ${user2.id}`);
console.log(`Total users: ${User.getUserCount()}`);

const user3 = new User("Charlie");
console.log(`Total users: ${User.getUserCount()}`);

Output:

User: Alice, ID: 1
Total users: 1
User: Bob, ID: 2
Total users: 2
Total users: 3

🔹 Utility Class Example

Static members are perfect for utility classes:

class StringUtils {
    static capitalize(str: string): string {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }
    
    static reverse(str: string): string {
        return str.split('').reverse().join('');
    }
    
    static truncate(str: string, maxLength: number): string {
        return str.length > maxLength 
            ? str.slice(0, maxLength) + '...' 
            : str;
    }
}

console.log(StringUtils.capitalize("hello"));        // Hello
console.log(StringUtils.reverse("world"));           // dlrow
console.log(StringUtils.truncate("Long text", 4));   // Long...

Output:

Hello
dlrow
Long...

🔹 Static vs Instance Comparison

Understanding when to use static vs instance members:

class Circle {
    static PI: number = 3.14159;  // Static: same for all circles
    radius: number;                // Instance: unique per circle
    
    constructor(radius: number) {
        this.radius = radius;
    }
    
    // Instance method: uses instance data
    getArea(): number {
        return Circle.PI * this.radius * this.radius;
    }
    
    // Static method: doesn't need instance data
    static compareAreas(c1: Circle, c2: Circle): string {
        if (c1.getArea() > c2.getArea()) return "First circle is larger";
        if (c1.getArea() < c2.getArea()) return "Second circle is larger";
        return "Circles are equal";
    }
}

const circle1 = new Circle(5);
const circle2 = new Circle(10);

console.log(circle1.getArea());                    // 78.53975
console.log(Circle.compareAreas(circle1, circle2)); // Second circle is larger

Output:

78.53975
Second circle is larger

💡 Key Points:

  • Static members belong to the class, not instances
  • Access static members using ClassName.memberName
  • Static methods cannot access instance properties with this
  • Perfect for utility functions, constants, and counters
  • Static members are shared across all instances

🧠 Test Your Knowledge

How do you access a static property named "count" in a class named "Counter"?