Skip to main content

Чи можна перевантажити (overload) конструктор?

1. Загальна ідея перевантаження конструктора

У TypeScript можна оголосити кілька сигнатур конструктора, але реалізувати - лише один (реальний) конструктор з перевірками всередині:

javascript
class User { name: string; age?: number; // Перевантаження (type-level only) constructor(name: string); constructor(name: string, age: number); // Реалізація одна constructor(name: string, age?: number) { this.name = name; this.age = age; } } const u1 = new User("Tim"); // працює const u2 = new User("Alex", 25); // працює const u3 = new User(); // Помилка: немає такого перевантаження

Перевантаження (constructor(...)) вище - лише сигнатури типів. Останній constructor(...) з тілом - реальна реалізація.


2. Як це працює під капотом

TypeScript компілює все в один JavaScript-конструктор, а перевантаження потрібні лише для перевірки типів на етапі компіляції.

javascript
// TS class User { constructor(name: string); constructor(name: string, age: number); constructor(name: string, age?: number) { console.log(name, age); } }

Компілюється в JS:

javascript
class User { constructor(name, age) { console.log(name, age); } }

Перевірки типів прибираються, залишається один конструктор.


3. Перевірка аргументів усередині конструктора

Оскільки JS не підтримує "реальні" перевантаження, усередині конструктора зазвичай роблять перевірки вручну:

javascript
class Point { x: number; y: number; constructor(x: number); constructor(x: number, y: number); constructor(x: number, y?: number) { if (y === undefined) { this.x = this.y = x; // якщо передано один аргумент } else { this.x = x; this.y = y; } } } new Point(5); // (5, 5) new Point(5, 10); // (5, 10)

4. Перевантаження з різними типами параметрів

Можна перевантажити конструктор за типами, а не лише за кількістю аргументів:

javascript
class FileData { path: string; buffer?: Uint8Array; constructor(path: string); constructor(buffer: Uint8Array); constructor(value: string | Uint8Array) { if (typeof value === "string") { this.path = value; } else { this.buffer = value; this.path = "memory.bin"; } } } new FileData("file.txt"); // string new FileData(new Uint8Array([1, 2])); // Uint8Array new FileData(123); // Помилка типів

5. Перевантаження через union-типи (альтернатива)

Іноді перевантаження можна замінити простим об'єднанням типів (|):

javascript
class User { constructor(public name: string | number) {} } new User("Tim"); new User(123);

Але при цьому TS не розрізняє сигнатури, і всередині конструктора потрібно вручну розбирати типи.


6. Перевантаження конструктора в базовому і успадкованому класі

Можна перевантажити конструктор у батьківському класі і викликати потрібний через super():

javascript
class Shape { color: string; constructor(); constructor(color: string); constructor(color = "black") { this.color = color; } } class Circle extends Shape { radius: number; constructor(radius: number); constructor(radius: number, color: string); constructor(radius: number, color?: string) { super(color); this.radius = radius; } } const c1 = new Circle(10); const c2 = new Circle(10, "red");

7. Важливий нюанс: перевантаження ≠ runtime-перевантаження

Усі сигнатури перевіряються лише компілятором і не існують у скомпільованому коді:

  • TypeScript перевіряє правильну кількість і типи аргументів.
  • JavaScript виконує єдиний конструктор з перевірками всередині.
  • Не можна мати дві реалізації конструктора.

Підсумок

МожливістьПідтримкаКоментар
Кілька сигнатур конструктораТакПеревіряються компілятором
Кілька реалізацій конструктораНіЛише одна з тілом
Перевантаження за кількістю аргументівТакЧерез ? або перевірки
Перевантаження за типамиТакЧерез об'єднання або сигнатури
Реальне runtime-перевантаження (як у C#/Java)НіНе можна
Перевірка типів при newТакПрацює завдяки сигнатурам

Коротко:

У TypeScript можна перевантажувати конструктори, але лише на рівні типів. Реалізація завжди одна, і всередині ти сам перевіряєш аргументи.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.