Дженерик (обобщённый тип) позволяет писать код, который работает с любым типом, но сохраняет связь между входом и выходом. Представьте функцию, возвращающую первый элемент массива. Без дженериков пришлось бы писать any и терять тип:
function first(arr: any[]): any { return arr[0]; }
С дженериком тип сохраняется. Угловые скобки <T> вводят параметр-тип:
function first<T>(arr: T[]): T { return arr[0]; }
const n = first([1, 2, 3]); // n: number const s = first(["a", "b"]); // s: string
T здесь — «заполнитель» для типа, который подставится при вызове. TypeScript сам определяет его по аргументу. Результат сохраняет точный тип — никакого any, полная подсказка дальше по коду.