Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Чи можна зробити generic-клас?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Так, класи в TypeScript можуть бути generic: параметр типу вказується як `class Box<T> { value: T; }` і задається при створенні екземпляра, наприклад `new Box<number>(123)`. **Ключове:** generic-клас може мати кілька параметрів, обмеження через `extends`, тип за умовчанням і успадковувати generic-параметри далі по ієрархії.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке generic-клас Generic-клас - це клас, у якому один або кілька типів (наприклад, `T`, `U`, `K`, `V`) передаються як параметри, щоб зробити його **гнучким і типобезпечним**. > Він не прив'язаний до конкретного типу даних, > а працює з будь-якими, зберігаючи строгу типізацію. --- ## 1. Найпростіший приклад ```javascript class Box<T> { private value: T; constructor(value: T) { this.value = value; } getValue(): T { return this.value; } } ``` Використання: ```javascript const box1 = new Box<number>(123); const box2 = new Box<string>("Hello"); console.log(box1.getValue()); // 123 console.log(box2.getValue()); // Hello ``` Тут `T` - універсальний параметр: - при створенні `Box<number>` → `T = number`, - при створенні `Box<string>` → `T = string`. TypeScript стежить, щоб тип був узгоджений: ```javascript box1.getValue().toFixed(2); // OK, T = number box2.getValue().toUpperCase(); // OK, T = string ``` --- ## 2. Generic-клас з кількома параметрами ```javascript class Pair<K, V> { constructor(public key: K, public value: V) {} describe() { console.log(`Key: ${this.key}, Value: ${this.value}`); } } const pair = new Pair<string, number>("age", 30); pair.describe(); // Key: age, Value: 30 ``` > Тут `K` - тип ключа, `V` - тип значення. > Можна використовувати будь-яку кількість generic-параметрів. --- ## 3. Generic-клас з обмеженням (`extends`) Можна обмежити тип параметра, щоб він відповідав певній структурі: ```javascript interface Identifiable { id: number; } class Repository<T extends Identifiable> { private items: T[] = []; add(item: T) { this.items.push(item); } findById(id: number): T | undefined { return this.items.find(i => i.id === id); } } const users = new Repository<{ id: number; name: string }>(); users.add({ id: 1, name: "Tim" }); users.add({ id: 2, name: "Alex" }); console.log(users.findById(2)); // { id: 2, name: 'Alex' } ``` > Тут `T` має бути об'єктом з `id: number`. > Це запобігає помилкам, якщо хтось спробує додати щось без `id`. --- ## 4. Generic-клас з типом за умовчанням Можна задати **тип за умовчанням**, якщо його не вказано при створенні: ```javascript class Storage<T = string> { private data: T[] = []; add(item: T) { this.data.push(item); } getAll(): T[] { return this.data; } } const s1 = new Storage(); // T = string (за умовчанням) s1.add("one"); s1.add("two"); const s2 = new Storage<number>(); s2.add(10); s2.add(20); ``` --- ## 5. Generic-клас + інтерфейси Інтерфейси теж можуть бути generic - і класи можуть їх реалізовувати: ```javascript interface IStorage<T> { add(item: T): void; getAll(): T[]; } class ArrayStorage<T> implements IStorage<T> { private data: T[] = []; add(item: T) { this.data.push(item); } getAll(): T[] { return this.data; } } ``` > Так можна створювати "типобезпечні контейнери". --- ## 6. Generic-клас з успадкуванням ```javascript class BaseResponse<T> { constructor(public data: T, public success: boolean) {} } class ApiResponse<T> extends BaseResponse<T> { constructor(data: T, public status: number) { super(data, status >= 200 && status < 300); } } const response = new ApiResponse({ id: 1, name: "Tim" }, 200); console.log(response.data.name); // Tim ``` > Дженерики можна **успадковувати і передавати далі** по ієрархії класів. --- ## Підсумок | Можливість | Приклад | Опис | |---|---|---| | Простий generic | `class Box<T> { ... }` | Типізує вміст | | Кілька параметрів | `class Pair<K, V>` | Кілька типів одночасно | | Обмеження | `<T extends SomeType>` | Обмежує допустимі типи | | Тип за умовчанням | `<T = string>` | Якщо тип не вказано | | Реалізація інтерфейсу | `class A<T> implements I<T>` | Спільно з generic-інтерфейсами | | Успадкування | `class B<T> extends A<T>` | Дженерики передаються далі |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.