Static Members & Parameter Properties

Difficulty: Intermediate

Static members in TypeScript belong to the class itself rather than to any specific instance. You access them using the class name, not through an instance. Static properties are shared across all instances and are commonly used for counters, configuration values, factory methods, and utility functions that are logically related to the class but don't depend on instance data.

Static methods are useful for creating factory functions, utility operations, and implementing patterns like the Singleton. A factory method is a static method that creates and returns instances of the class, often with some logic to determine which subclass or configuration to use. The Singleton pattern uses a private constructor combined with a static method to ensure only one instance of a class exists.

Parameter properties are a TypeScript shorthand that lets you declare and initialize class properties directly in the constructor parameter list. By adding an access modifier (`public`, `private`, `protected`) or `readonly` before a constructor parameter, TypeScript automatically creates a property with that name and assigns the parameter value to it. This eliminates the repetitive pattern of declaring a property, then assigning it in the constructor body.

Parameter properties are purely a TypeScript convenience feature. They produce the same JavaScript output as manual property declaration and assignment, but with much less boilerplate. They are especially valuable when a class has many properties that are simply passed through the constructor without any transformation. Interviewers often ask about this feature because it tests understanding of TypeScript-specific syntax and how it relates to the generated JavaScript.

Code examples

Static Properties and Methods

class IdGenerator {
  private static nextId: number = 1;

  static generate(): string {
    return `id-${IdGenerator.nextId++}`;
  }

  static reset(): void {
    IdGenerator.nextId = 1;
  }
}

console.log(IdGenerator.generate());
console.log(IdGenerator.generate());
console.log(IdGenerator.generate());
IdGenerator.reset();
console.log(IdGenerator.generate());

The static `nextId` property is shared across the class. Each call to `generate()` increments it. `reset()` restores it to 1. No instance is needed.

Parameter Properties Shorthand

// Without parameter properties (verbose)
class UserVerbose {
  public name: string;
  private email: string;
  readonly id: number;

  constructor(name: string, email: string, id: number) {
    this.name = name;
    this.email = email;
    this.id = id;
  }
}

// With parameter properties (concise)
class User {
  constructor(
    public name: string,
    private email: string,
    readonly id: number
  ) {}

  getEmail(): string {
    return this.email;
  }
}

const user = new User("Alice", "alice@test.com", 1);
console.log(user.name);
console.log(user.getEmail());
console.log(user.id);

Both classes produce identical JavaScript. Parameter properties eliminate the boilerplate of declaring and assigning each property manually.

Static Factory Method

class Connection {
  private static instance: Connection | null = null;

  private constructor(private host: string, private port: number) {}

  static create(host: string, port: number): Connection {
    if (!Connection.instance) {
      Connection.instance = new Connection(host, port);
    }
    return Connection.instance;
  }

  describe(): string {
    return `${this.host}:${this.port}`;
  }
}

const conn1 = Connection.create("localhost", 5432);
const conn2 = Connection.create("remote", 3306);
console.log(conn1.describe());
console.log(conn1 === conn2);

This Singleton pattern uses a private constructor and a static factory method. The second call returns the same instance, so conn1 === conn2 is true.

Key points

Concepts covered

static properties, static methods, parameter properties, shorthand constructor, singleton pattern