Обобщения (Generics) позволяют создавать компоненты, способные работать с различными типами данных, сохраняя при этом строгую типизацию. Generic классы — это классы, которые принимают один или несколько параметров типа при создании экземпляра.
Представьте коробку, на которой при производстве можно написать, что в ней будет храниться: обувь, книги или электроника. Синтаксис выглядит как class Box, где T — это переменная типа. Внутри класса мы используем T как обычный тип для свойств и методов.
Это позволяет создавать универсальные структуры данных: стеки, очереди, списки, обертки ответов API, не привязываясь к конкретным типам (string, number) заранее и не теряя проверок типов, как это бывает с any.
- Модуль 1: Введение в TypeScript
- Модуль 2: Примитивные типы
- Модуль 3: Специальные типы
- Модуль 4: Массивы
- Модуль 5: Кортежи (Tuples)
- Модуль 6: Объекты
- Модуль 7: Функции
- Модуль 8: Union типы
- Модуль 9: Литеральные типы
- Модуль 10: Type Aliases
- Модуль 11: Интерфейсы
- Модуль 12: Type Guards и Narrowing
- Модуль 13: Enums
- Модуль 14: Классы
- Модуль 15: Generics — основы
- Модуль 16: Generics — ограничения
- Модуль 17: Utility Types — базовые
- Модуль 18: Utility Types — работа с Union
- Модуль 19: Utility Types — функции
- Модуль 20: Type Assertions
- Модуль 21: Keyof и Typeof операторы
- Модуль 22: Mapped Types
- Модуль 23: Conditional Types
- Модуль 24: Discriminated Unions
- Модуль 25: Модули и типы
- Модуль 26: Declaration Files
- Модуль 27: Типизация асинхронного кода
- Модуль 28: Практические паттерны
1. Объявление generic класса
Дополните объявление generic класса Box, который является контейнером для значения произвольного типа. Впишите параметр типа в заголовок класса и укажите тип свойства value, чтобы класс мог корректно хранить и возвращать значение. Используйте параметр типа T, как принято в TypeScript.
class Box<input1S> {
private value: input2S;
constructor(value: input2S) {
this.value = value;
}
getValue(): input2S {
return this.value;
}
}2. Порядок создания и использования
Перед вами строки TypeScript-кода, демонстрирующие создание и использование generic-класса. Они перемешаны. Восстановите правильную последовательность, чтобы получился корректный код: сначала объявление generic-класса Box с полем value и методом setValue, затем создание экземпляра этого класса с конкретным типом number и, наконец, вызов метода setValue для установки числового значения. Обратите внимание на порядок объявления класса, его членов и последующего использования.
class Box<T> { setValue(val: T) { this.value = val; }const numberBox = new Box<number>();numberBox.setValue(10); value: T; }3. Инстанцирование с типом
В этом задании вам нужно создать экземпляр generic-класса Storage, указав правильный тип данных в угловых скобках, чтобы он соответствовал передаваемому аргументу конструктора. Выберите подходящие типы из выпадающего списка для каждого пропуска, чтобы код стал корректным с точки зрения системы типов TypeScript. Обратите внимание, что тип в угловых скобках должен соответствовать типу значения, передаваемого в конструктор.
class Storage<T> {
constructor(public value: T) {}
}
// Создайте экземпляры с правильными типами
let stringStorage = new Storage<input1S>("Hello");
let numberStorage = new Storage<input2S>(42);
let booleanStorage = new Storage<input3S>(true);
let arrayStorage = new Storage<input4S>([1, 2, 3]);4. Соответствие типов
В левой колонке приведены объявления переменных generic-класса Box с различными типами-параметрами. В правой колонке перечислены значения. Сопоставьте каждое объявление переменной со значением, которое можно передать в метод add() этого экземпляра Box. Обратите внимание, что тип значения должен строго соответствовать generic-параметру класса Box. Всего необходимо сопоставить 6 пар.
let box1 = new Box<string>();let box2 = new Box<number>();let box3 = new Box<boolean>();let box4 = new Box<string[]>();let box5 = new Box<number[]>();let box6 = new Box<{ name: string; }>();{ name: 'John' }'hello'true123['a', 'b'][1, 2, 3]5. Несоответствие типов в Generic
В данном фрагменте кода TypeScript используется generic-класс для работы с числами, но при вызове метода допущена ошибка, приводящая к несоответствию типов. Найдите и исправьте строку, где передаётся значение неподходящего типа, чтобы код мог успешно скомпилироваться и выполниться.
class Stack<T> { private items: T[] = []; push(item: T): void { this.items.push(item); } pop(): T | undefined { return this.items.pop(); }} const numberStack = new Stack<number>();numberStack.push("25");console.log(numberStack.pop());6. Анализ работы стека
Проанализируйте TypeScript-код сверху и восстановите последовательность логических шагов выполнения программы. Шаги снизу перемешаны — расставьте их в правильном порядке, чтобы отразить, как программа создает стек, добавляет элементы, извлекает их и проверяет состояние.
class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
size(): number {
return this.items.length;
}
isEmpty(): boolean {
return this.items.length === 0;
}
}
const numberStack = new Stack<number>();
numberStack.push(10);
numberStack.push(20);
console.log(numberStack.pop());
console.log(numberStack.size());
console.log(numberStack.pop());
console.log(numberStack.isEmpty());7. Класс пары значений
Из предложенных строк соберите корректный TypeScript-класс KeyValuePair с двумя generic-параметрами K и V, который содержит приватные поля key и value, а также конструктор для их инициализации. Игнорируйте лишние строки, не входящие в минимальное решение. Порядок объявления полей key и value между собой не важен, так же как и порядок присваивания в конструкторе.
class KeyValuePair<K, V> { private key: K; private value: V; constructor(key: K, value: V) { this.key = key; this.value = value; }}class KeyValuePair { public getKey(): K { return this.key; } setValue(value: V): void { this.value = value; }