Розв'язання проблеми з ініціалізацією властивості в конструкторі TypeScript через деструктуризацію об'єкта

Розв’язання проблеми з ініціалізацією властивості в конструкторі TypeScript через деструктуризацію об’єкта

5 Березня 2024 в 19:51 24

При розробці програмного забезпечення на мові TypeScript, розробники часом можуть зіткнутися з питаннями, пов’язаними з ініціалізацією властивостей в конструкторах класів. Одним із таких питань є помилка, яку видає TypeScript при спробі ініціалізувати властивість в конструкторі за допомогою деструктуризації об’єкта.

Це явище може бути дещо плутаним на перший погляд, оскільки здається, що властивість була ініціалізована в конструкторі, проте TypeScript видає помилку, що властивість не має початкового значення і не визначена в конструкторі. Давайте розглянемо цей випадок докладніше та розглянемо можливі причини і способи вирішення цієї проблеми.

Уявімо, що ми маємо клас Watcher, який приймає об’єкт конфігурації у своєму конструкторі та ініціалізує властивість step через деструктуризацію:

typescript
Copy code
class Watcher {
step: number;
constructor(config: { step: number }) {
const { step } = config;
this.step = step;
}
}
const w = new Watcher({ step: 1 });

На перший погляд, все виглядає правильно: ми передаємо об’єкт конфігурації з властивістю step у конструктор Watcher і ініціалізуємо step через деструктуризацію. Однак, TypeScript видає помилку: ‘Property ‘step’ has no initializer and is not definitely assigned in the constructor.’

Ця помилка виникає через те, що TypeScript не розуміє, що деструктуризація об’єкта в конструкторі гарантує ініціалізацію властивості. Для TypeScript це все одно, що ми просто декларуємо, що властивість існує, але не надаємо їй значення.

Щоб уникнути цієї помилки, ми можемо застосувати кілька підходів. Один із них – це використання анотації типу для вказівки TypeScript на те, що властивість буде ініціалізована пізніше. Для цього ми можемо встановити тип властивості step як undefined:

typescript
Copy code
class Watcher {
step: number | undefined;
constructor(config: { step: number }) {
const { step } = config;
this.step = step;
}
}
const w = new Watcher({ step: 1 });

Іншим підходом може бути використання параметра конструктора зі значенням за замовчуванням, який дозволяє TypeScript розуміти, що властивість буде ініціалізована в конструкторі:

typescript
Copy code
class Watcher {
step: number;
constructor(config: { step: number } = { step: 0 }) {
const { step } = config;
this.step = step;
}
}
const w = new Watcher({ step: 1 });

Обидва ці підходи дозволяють уникнути помилки від TypeScript та забезпечують правильну ініціалізацію властивостей у конструкторі.