Как передать любой тип используя дженерики?

В языке TypeScript можно использовать дженерики для передачи любого типа данных. Дженерики позволяют задавать параметры типа, которые будут использоваться как аргументы функций, методов, классов и интерфейсов.

Для передачи любого типа используются универсальные параметры типа. Универсальный параметр типа обозначается с помощью записи <T>, где T - имя параметра типа, которое может быть любым допустимым идентификатором или символом.

Пример использования дженериков для передачи любого типа:

function printValue<T>(value: T): void {
  console.log(value);
}

printValue("Hello, TypeScript!"); // выводит "Hello, TypeScript!"
printValue(42); // выводит 42
printValue(true); // выводит true

В этом примере функция printValue принимает аргумент value типа T и выводит его в консоль. При вызове функции printValue мы можем передать любой тип данных, и TypeScript самостоятельно определит тип T на основе аргумента, который мы передаем.

Также можно использовать дженерики для определения типа внутри классов и интерфейсов. Например:

interface Collection<T> {
  add(item: T): void;
  remove(item: T): void;
  clear(): void;
  contains(item: T): boolean;
}

class List<T> implements Collection<T> {
  private items: T[] = [];

  add(item: T): void {
    this.items.push(item);
  }

  remove(item: T): void {
    const index = this.items.indexOf(item);
    if (index > -1) {
      this.items.splice(index, 1);
    }
  }

  clear(): void {
    this.items = [];
  }

  contains(item: T): boolean {
    return this.items.includes(item);
  }
}

const list = new List<number>();
list.add(1);
list.add(2);
list.add(3);
console.log(list.contains(2)); // выводит true
console.log(list.contains(4)); // выводит false

В этом примере определен интерфейс Collection, использующий дженерик T для определения типа элементов коллекции. Класс List реализует этот интерфейс, а тип T для него определен как number. Мы создаем экземпляр класса List, добавляем несколько чисел и проверяем наличие элементов в списке. Все операции выполняются с элементами типа number.

Таким образом, дженерики позволяют нам передавать любой тип данных и использовать его в функциях, классах или интерфейсах, что делает код более гибким и переиспользуемым.