Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що дають константні параметри типу (const T) і як керувати виведенням у узагальнених функціях?

За замовчуванням TypeScript виводить параметри типу розширено: літерали стають string, масиви - звичайними масивами.

function routes<T extends readonly string[]>(paths: T): T {
  return paths;
}

const r = routes(['/home', '/about']);   // string[] - назви маршрутів втрачено

Раніше викликач мусив писати as const на кожному виклику: routes(['/home', '/about'] as const).

Константний параметр типу (TS 5.0) переносить цю вимогу в оголошення функції:

function routes<const T extends readonly string[]>(paths: T): T {
  return paths;
}

const r = routes(['/home', '/about']);   // readonly ['/home', '/about']
type Route = (typeof r)[number];          // '/home' | '/about'

Аргумент виводиться так, ніби його записано з as const.

Важлива деталь - readonly в обмеженні. Якщо обмеження - змінюваний масив (T extends string[]), const не допоможе: readonly-кортеж не можна присвоїти string[], і TypeScript відкотиться до string[]. Тому обмеження пишуть як readonly unknown[].

Де корисно:

  • конфігурації й реєстри: маршрути, ключі подій, назви полів форм, налаштування таблиць - тип будується з літералів, переданих викликачем;
  • builder-API: defineConfig({ ... }), createRoutes([...]), createStore({ ... }) - бібліотеки отримують точні типи без as const у користувача.

Інші способи керувати виведенням:

  • NoInfer<T> (TS 5.4) - заборонити виводити T з певного аргументу, щоб той лише перевірявся;
  • обмеження з літералами: T extends 'sm' | 'md' | 'lg' - тоді T виводиться як конкретний літерал, а не string;
  • порядок аргументів: TypeScript виводить параметри зліва направо, і колбеки з неанотованими параметрами отримують типи від попередніх аргументів. Тому функції на кшталт useQuery(key, fetcher) чи pipe(value, ...fns) проєктують так, щоб «джерело» типу йшло першим;
  • явні аргументи типу fn<User>(...) - останній варіант: TypeScript не підтримує часткового виведення, тож явно доведеться вказати всі параметри без значень за замовчуванням.

Пастка: const не робить значення незмінним під час виконання - лише впливає на виведений тип (з readonly в ньому).

Докладніше в документації: TypeScript 5.0: const-параметри типу

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання