Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Чи можна перевантажити (overload) конструктор?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)У TypeScript можна оголосити **кілька сигнатур конструктора**, але реалізувати - лише один реальний конструктор з перевірками всередині. **Ключове:** перевантаження існують лише на рівні типів і перевіряються компілятором, тоді як у скомпільованому JavaScript залишається єдиний конструктор без реальних runtime-перевантажень.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 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 можна перевантажувати конструктори, > але лише **на рівні типів**. > Реалізація завжди **одна**, і всередині ти сам перевіряєш аргументи.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.