У TypeScript ключове слово static використовується для оголошення властивостей і методів, які належать самому класу, а не його екземплярам. Такі члени класу викликаються без створення об’єкта – напряму через ім’я класу, і не доступні безпосередньо з екземплярів.

Коли використовувати static

static варто застосовувати тоді, коли властивість або метод:

  • спільні для всіх екземплярів класу
  • не залежать від конкретного об’єкта чи його стану
  • виконують службову чи допоміжну функцію

Деякі приклади:

  • константи та конфігураційні значення класу
  • лічильники кількості створених екземплярів
  • допоміжні методи (наприклад, перетворення чи форматування даних)

Як працює static у TypeScript

Приклад:

class MathUtils {
  static PI = 3.14159;

  static calculateCircleArea(radius: number): number {
    return this.PI * radius * radius;
  }
}

console.log(MathUtils.PI); // 3.14159
console.log(MathUtils.calculateCircleArea(5)); // 78.53975

Пояснення:

  • властивість PI та метод calculateCircleArea() належать класу MathUtils, а не його екземплярам
  • доступ до них здійснюється через ім’я класу (MathUtils.PI, MathUtils.calculateCircleArea()), і створювати об’єкт за допомогою new MathUtils() не потрібно

Різниця між static і звичайними методами/властивостями

Доступ з об’єктаДоступ з класуПриклад
Звичайний методТакНіobj.method()
Статичний методНіТакClassName.method()
Звичайна властивістьТакНіobj.prop
Статична властивістьНіТакClassName.prop

Приклад:

class Example {
  static staticValue = 'static value';
  instanceValue = 'instance value';

  static staticMethod() {
    console.log('Static method');
  }

  instanceMethod() {
    console.log('Instance method');
  }
}

const obj = new Example();

console.log(Example.staticValue); // ok
Example.staticMethod(); // ok

console.log(obj.instanceValue); // ok
obj.instanceMethod(); // ok

// Помилки:
console.log(obj.staticValue);
obj.staticMethod();

Приклад використання static для лічильника об’єктів класу

class User {
  static userCount = 0;
  name: string;

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

  static getUserCount(): number {
    return User.userCount;
  }
}

const alice = new User('Alice');
const bob = new User('Bob');

console.log(User.getUserCount()); // 2

Цей код рахує, скільки об’єктів класу User було створено. Властивість userCount – статична, вона належить самому класу й існує як єдина копія, незалежно від кількості створених об’єктів. Щоразу, коли виконується new User(...), конструктор збільшує значення лічильника. Метод getUserCount() теж є статичним і повертає поточне значення лічильника, тому він викликається як User.getUserCount(), а не через екземпляр.

Статичні блоки ініціалізації

Починаючи з TypeScript 4.4, можна використовувати static { ... } для більш складної ініціалізації статичних властивостей:

class Config {
  static settings: Record<string, string>;

  static {
    this.settings = {
      apiUrl: 'https://api.example.com',
      version: '1.0.0',
    };
    console.log('Static block executed');
  }
}

console.log(Config.settings.apiUrl);

// Static block executed
// https://api.example.com

Статичний блок static { … } виконується один раз під час завантаження класу, коли інтерпретатор вперше обробляє його визначення, ще до створення будь-яких екземплярів. Усередині блоку можна працювати лише зі статичними властивостями та методами класу – через this або безпосередньо через ім’я класу.

Це зручно для:

  • складної ініціалізації статичних властивостей
  • підготовки початкових даних (наприклад, конфігурації)
  • обробки помилок ініціалізації за допомогою try…catch

Статичні блоки не можуть бути позначені як async, але всередині можна викликати асинхронні методи або API, що повертають Promise.

Приклад з обробкою помилок:

class Config {
  static settings: Record<string, string>;

  static {
    try {
      // Імітація завантаження налаштувань
      const raw = '{ "apiUrl": "https://api.example.com", "version": "1.0.0" }';
      this.settings = JSON.parse(raw);
      console.log('Static block executed');
    } catch (error) {
      console.error('Failed to initialize settings:', error);
      this.settings = { apiUrl: '', version: '' }; // Значення за замовчуванням
    }
  }
}

console.log(Config.settings.apiUrl);

// Static block executed
// https://api.example.com

У класі може бути кілька статичних блоків, і вони виконуються послідовно в тому порядку, в якому оголошені.

Коли не варто зловживати використанням static

  • метод залежить від стану конкретного об’єкта – у такому разі він не повинен бути статичним
  • велика кількість static може фактично перетворити клас на набір глобальних змінних, що ускладнить підтримку та тестування

Підсумок

Ключове слово static у TypeScript дозволяє створювати властивості та методи, що належать класу, а не його екземплярам. Це зручно для констант, службових методів і спільних налаштувань. Правильне використання static робить код більш структурованим, зрозумілим і зручним у використанні.


Мітки: