Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Static Members, Getters, and Setters in TypeScript

Static Members, Getters, and Setters

~14 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

To wrap up Phase 3 (object-oriented programming): two tools enabling INSTANCE-independent functionality (static) and controlled property access with normal dot syntax (get/set).

Static members: belong to the class, not the instance

export class Library {
  private static nextId = 1; // belongs to the CLASS, not to a single library
  public readonly id: number;
  private stock: Book[];

  constructor(initialStock: Book[]) {
    this.id = Library.nextId++; // access via the class name, not 'this'
    this.stock = initialStock;
  }
}

const a = new Library([]);
const b = new Library([]);
console.log(a.id, b.id); // 1, 2 - each instance gets a UNIQUE, sequential ID

static nextId exists EXACTLY ONCE, shared by ALL instances of Library – unlike stock, which EVERY instance has its own copy of. Access happens via Library.nextId (the class name), NOT this.nextId.

Static methods: utility functions bound to the class

export class Book {
  // ... existing properties

  static isValidIsbn(isbn: string): boolean {
    const cleaned = isbn.replace(/-/g, '');
    return cleaned.length === 13 && /^\d+$/.test(cleaned);
  }
}

Book.isValidIsbn('978-0-618-64015-7'); // true - CALLED via the class name, no instance needed

static isValidIsbn(...) needs NO Book instance to be called – useful for helper functions that logically BELONG to a class (ISBN validation is a "book" concept), but don't need access to this.

Getters and setters: computed properties with dot syntax

export class Book extends Medium {
  private _pageCount: number;

  constructor(/* ... */ pageCount: number) {
    super(/* ... */);
    this._pageCount = pageCount;
  }

  get pageCount(): number {
    return this._pageCount;
  }

  set pageCount(value: number) {
    if (value <= 0) {
      throw new Error('Page count must be positive.');
    }
    this._pageCount = value;
  }

  get readingTimeMinutes(): number {
    return Math.round(this._pageCount * 1.5); // COMPUTED value, not a real property
  }
}

const book = new Book(/* ... */ 300);
console.log(book.pageCount);          // 300 - reads like a regular property, but calls the GETTER
book.pageCount = 350;                 // writes like a regular property, calls the SETTER
book.pageCount = -10;                 // throws the Error from the setter
console.log(book.readingTimeMinutes); // 450 - ONLY a getter, no matching setter -> read-only

From OUTSIDE, book.pageCount looks like an ORDINARY property (no parentheses like a method call!) – INTERNALLY, your own code runs on every read/write. The leading underscore _pageCount is a pure NAMING CONVENTION (not TypeScript-specific), to distinguish the "real", private data storage from the public getter/setter pair.

Only a getter: automatically read-only

readingTimeMinutes has ONLY a get, NO set – trying book.readingTimeMinutes = 100 would trigger a compile-time error. That's a MORE ELEGANT equivalent to readonly from chapter 7/11 for values that are COMPUTED instead of stored.

Achtung: Getters/setters feel "magic", but be careful with EXCESSIVE logic inside them – a getter that does expensive computations or even network calls surprises callers who assume book.pageCount is a simple, cheap property read. Rule of thumb: getters/setters for SIMPLE validation and light computation, real asynchronous/expensive operations belong in explicitly named methods.

Tipp: That wraps up Phase 3 (OOP) – classes, inheritance, access modifiers, abstract classes, static members, getters/setters. Phase 4 turns to the GENUINELY advanced TypeScript features, starting with generics – the tool that makes our somewhat repetitive Library class REUSABLE for ANY medium type, not just books.