Skip to content

Дженерики TypeScript объяснённые

Шаблоны дженериков, к которым вы прибегаете чаще всего, сгруппированные по задаче: объявить параметр типа, ограничить его, задать значение по умолчанию, ветвить условным типом, захватить через infer и отобразить форму. Каждая строка сопоставляет шаблон с однострочным примером.

Дженерик — это параметр типа: заполнитель для типа, который выбирает вызывающий, поэтому одна функция или тип подходит для многих форм без потери точности. Читайте <T> как «для некоторого типа T». Сила заключается в ограничении T, ветвлении по нему и отображении его. Шаблоны ниже — рабочий словарь.

Справочная таблица · 28 записи
28 of 28 rows
Объявление
Параметр типа, который выбирает вызывающий.function first<T>(xs: T[]): T
Несколько независимых параметров типа.function pair<T, U>(a: T, b: U): [T, U]
Второй параметр, связанный с ключами первого.function get<T, K extends keyof T>(o: T, k: K): T[K]
Класс с параметром типа в полях и методах.class Box<T> { value: T }
Форма объекта с параметром типа.interface Result<T> { data: T }
Параметр типа в стрелочной функции; запятая в конце не даёт файлам .tsx прочитать его как JSX.const first = <T,>(xs: T[]): T => xs[0]
Ограничение
Требует, чтобы T был присваиваем к Type.function len<T extends { length: number }>(x: T)
Ограничивает T ключом другого типа.type Keys<O> = keyof O
Ограничивает T конструируемым классом.function make<C extends new () => C>(c: C): C
Требует, чтобы T удовлетворял нескольким ограничениям одновременно.function log<T extends Error & { code: number }>(e: T)
Ограничивает чем угодно; сохраняет параметр универсальным, не сужая его.type Wrap<T> = T extends unknown ? { v: T } : never
По умолчанию и infer
Даёт T значение по умолчанию, если вызывающий его не указал.function parse<T = string>(): T
Захватывает тип внутри условного.type El<T> = T extends Array<infer I> ? I : never
Разворачивает вложенный Promise до его внутреннего типа.type Data = Awaited<Promise<User>>
Захватывает один фрагмент типа шаблонного литерала.type Path<S> = S extends `/api/${infer R}` ? R : never
Проверяет всё объединение сразу; голый T выводит по одному члену за раз.type El<T> = [T] extends [Array<infer I>] ? I : never
Условные и отображаемые
Выбирает тип в зависимости от того, присваиваем ли T к U.type IsStr<T> = T extends string ? true : false
Строит новый тип объекта, преобразуя каждый ключ T.type Frozen<T> = { [K in keyof T]: Readonly<T[K]> }
Объект, ключи которого — K, а значения — V.type Scores = Record<string, number>
Встроенные дженерики, производные от шаблонов выше.type Preview = Pick<User, "id" | "name">
Голый T перед extends выполняется один раз на член объединения и объединяет результаты.ToArray<'a' | 'b'> = 'a'[] | 'b'[]
Добавляет или убирает модификаторы у отображённых ключей.type Req<T> = { [K in keyof T]-?: T[K] }
Ключи значения времени выполнения, как тип.const opts = { a: 1 }; type K = keyof typeof opts
Строит строковый тип из других строковых типов.type Route = `/users/${string}`
Соединяет типы-кортежи встык.type Concat<T extends unknown[], U extends unknown[]> = [...T, ...U]
Тип, чьё определение ссылается на себя.type Json = string | number | Json[] | { [k: string]: Json }
Проверяет значение против типа и сохраняет его более узкий литеральный тип.const c = { dark: "#000" } satisfies Record<string, string>
Сохраняет литеральный тип вызывающего вместо расширения (TS 5.0).function first<const T>(xs: readonly T[]): T