Обобщения: T extends и ограничения
Пишите обобщённые функции и интерфейсы, ограничивайте параметры типов с помощью extends и используйте значения типов по умолчанию для гибких API.
«Обобщения: T extends и ограничения» — бесплатный урок Frontend Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.
Что такое обобщения
Обобщения позволяют писать функции, классы и интерфейсы, работающие с несколькими типами и сохраняющие типобезопасность. Вместо отдельных функций для каждого типа вы пишете одну обобщённую функцию, параметризованную переменной типа.
Простая обобщённая функция
Параметр типа T объявляется в угловых скобках. TypeScript выводит T из типа аргумента — явная аннотация в месте вызова не нужна.
function identity<T>(value: T): T {
return value;
}
identity(42); // T is inferred as number, returns number
identity('hello'); // T inferred as string
identity<boolean>(true); // explicitОбобщённые интерфейсы и типы
Параметризуйте интерфейсы и типы с помощью обобщений, чтобы описывать повторно используемые структуры данных.
interface Box<T> {
value: T;
label?: string;
}
const numBox: Box<number> = { value: 42 };
const strBox: Box<string> = { value: 'hello', label: 'greeting' };extends — ограничения обобщённых типов
Используйте T extends SomeType, чтобы ограничить допустимые значения T. Функция принимает только типы, удовлетворяющие этому ограничению.
function getLength<T extends { length: number }>(item: T): number {
return item.length; // safe: T is guaranteed to have length
}
getLength('hello'); // 5
getLength([1, 2, 3]); // 3
getLength({ length: 7 }); // 7
// getLength(42); // Error: number has no lengthkeyof и ограничения обобщений
keyof T создаёт объединение ключей свойств T. В сочетании с обобщениями это обеспечивает типобезопасный доступ к свойствам.
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: 'Alice', age: 30 };
getProperty(user, 'name'); // string
getProperty(user, 'age'); // number
// getProperty(user, 'foo'); // ErrorЗначения типов по умолчанию
Задайте тип по умолчанию для параметра обобщения с помощью T = DefaultType. Это используется, когда существует подходовое значение по умолчанию, но вызывающий код может его переопределить.
interface Paginated<T = unknown> {
items: T[];
total: number;
page: number;
}
const rawPage: Paginated = { items: [], total: 0, page: 1 };
const typedPage: Paginated<User> = { items: [], total: 0, page: 1 };Несколько параметров типов
Функции могут иметь несколько независимых параметров типов.
function zip<A, B>(arrA: A[], arrB: B[]): Array<[A, B]> {
return arrA.map((a, i) => [a, arrB[i]]);
}
zip([1, 2, 3], ['a', 'b', 'c']);
// [[1,'a'], [2,'b'], [3,'c']]Обобщённые классы
Классы тоже могут быть обобщёнными. Это часто используется в структурах данных, таких как стеки, очереди и наблюдаемые хранилища.
class Stack<T> {
private items: T[] = [];
push(item: T) { this.items.push(item); }
pop(): T | undefined { return this.items.pop(); }
peek(): T | undefined { return this.items.at(-1); }
get size() { return this.items.length; }
}
const stack = new Stack<number>();
stack.push(1);
stack.push(2);
stack.pop(); // 2Асинхронные обобщённые функции
Асинхронные обобщённые функции часто используются для типизированных вызовов API.
async function fetchJson<T>(url: string): Promise<T> {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json() as Promise<T>;
}
const users = await fetchJson<User[]>('/api/users');
const profile = await fetchJson<UserProfile>('/api/me');infer в условных типах
Ключевое слово infer внутри условного типа извлекает тип из шаблона. Оно используется в коде библиотек для извлечения возвращаемого типа функции или типа элементов массива.
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type ElementType<T> = T extends Array<infer E> ? E : never;
type Fn = () => { name: string };
type Result = ReturnType<Fn>; // { name: string }Когда использовать обобщения
Используйте обобщения, когда: 1) одна и та же логика применяется к нескольким типам; 2) нужна связь между типами входных и выходных данных; 3) вы создаёте повторно используемую структуру данных или утилиту. Не используйте обобщения без необходимости — конкретные типы понятнее, если есть только один вариант использования.
Быстрая проверка
Что гарантирует ограничение T extends { length: number }?
Итоги: обобщения
Обобщения параметризуют типы, поэтому одна функция, класс или интерфейс может работать с несколькими типами. T extends SomeType добавляет ограничения. keyof T возвращает объединение ключей свойств. Значения по умолчанию задаются с помощью T = Default. infer извлекает типы в условных типах. Используйте обобщения для повторно используемых типизированных утилит и структур данных.
Часто задаваемые вопросы
Урок «Обобщения: T extends и ограничения» бесплатный?
Да — полный текст урока «Обобщения: T extends и ограничения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.
Чему я научусь в уроке «Обобщения: T extends и ограничения»?
Пишите обобщённые функции и интерфейсы, ограничивайте параметры типов с помощью extends и используйте значения типов по умолчанию для гибких API. Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Frontend Academy?
Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Обобщения: T extends и ограничения»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Frontend Academy?
Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Обобщения: T extends и ограничения
- Вспомогательные типы: Partial, Required, Pick и Omit
- Отображаемые и условные типы
- Сужение типов: typeof, instanceof и дискриминируемые объединения