Generic классы

Тренажер по TypeScript для пользователей с начальным уровнем подготовки.

Тренажер по TypeScript

Обобщения (Generics) позволяют создавать компоненты, способные работать с различными типами данных, сохраняя при этом строгую типизацию. Generic классы — это классы, которые принимают один или несколько параметров типа при создании экземпляра.

Представьте коробку, на которой при производстве можно написать, что в ней будет храниться: обувь, книги или электроника. Синтаксис выглядит как class Box, где T — это переменная типа. Внутри класса мы используем T как обычный тип для свойств и методов.

Это позволяет создавать универсальные структуры данных: стеки, очереди, списки, обертки ответов API, не привязываясь к конкретным типам (string, number) заранее и не теряя проверок типов, как это бывает с any.

Список тем

1. Объявление generic класса

id: 40715_generic_cls_01_replace

Дополните объявление generic класса Box, который является контейнером для значения произвольного типа. Впишите параметр типа в заголовок класса и укажите тип свойства value, чтобы класс мог корректно хранить и возвращать значение. Используйте параметр типа T, как принято в TypeScript.

Заполните пропуски
class Box<input1S> {
    private value: input2S;

    constructor(value: input2S) {
        this.value = value;
    }

    getValue(): input2S {
        return this.value;
    }
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

2. Порядок создания и использования

id: 40715_generic_cls_02_sequencing

Перед вами строки 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. Инстанцирование с типом

id: 40715_generic_cls_03_select

В этом задании вам нужно создать экземпляр 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]);
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

4. Соответствие типов

id: 40715_generic_cls_04_compare

В левой колонке приведены объявления переменных 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'
true
123
['a', 'b']
[1, 2, 3]
Сообщения
Проверить
Показать подсказку

5. Несоответствие типов в Generic

id: 40715_generic_cls_05_error

В данном фрагменте кода 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());
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

6. Анализ работы стека

id: 40715_generic_cls_06_analyze

Проанализируйте 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());
Расположите элементы в логичном порядке
В стек добавляется число 20 (второй вызов push)
Проверяется текущий размер стека (size) — возвращается 1
В стек добавляется число 10 (первый вызов push)
Создается экземпляр стека для чисел (Stack)
Извлекается следующий элемент стека (pop) — возвращается 10
Проверяется, пуст ли стек (isEmpty) — возвращается true
Извлекается верхний элемент стека (pop) — возвращается 20
Сообщения
Проверить
Показать подсказку

7. Класс пары значений

id: 40715_generic_cls_07_build

Из предложенных строк соберите корректный 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; }
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

TypeScript: компиляция и запуск

id: 40715_compiler

Этот пример показывает, как создавать универсальные классы с помощью Generics в TypeScript. Класс Box может хранить значения любого типа, сохраняя при этом типобезопасность. Попробуйте: измените типы в строках 19-21, добавьте новые методы в класс Box, создайте экземпляры с разными типами данных (массивами, объектами). Экспериментируйте с ограничениями дженериков (extends) - что произойдет, если попытаться создать Box с типом, не соответствующим ограничению?

TS
Запустить тренажёр (TypeScript)
НайтиКурс.Ру