TGViewer
Катерина | Про Frontend Катерина | Про Frontend @katerina_profrontend · 2.87K subscribers
Post #1545 1.67K
Распределение условных типов и infer в TypeScript 🤩

В TypeScript условные типы по умолчанию распространяются по объединениям (A | B). Это часто полезно, но иногда приводит к неожиданным результатам. Простое и надёжное решение — спрятать параметр в кортеж: [T] extends [X] ? ...

🧩 Проблема:

Условный тип вида T extends X ? A : B при подстановке T = A | B автоматически разбивается и проверяется для каждого члена объединения отдельно. Такой механизм называется distributive conditional types.


type IsString<T> = T extends string ? "yes" : "no";
type R = IsString<string | number>; // "yes" | "no"


Ожидание «всё или ничего» (весь тип — строка?) нарушается: вместо одного ответа получаем объединение ответов для частей. 😥

🧩 Решение:

Чтобы проверить весь тип одним выражением (не по частям), нужно «спрятать» T внутри другой структуры — самый простой приём: кортеж.


type IsStringStrict<T> = [T] extends [string] ? "yes" : "no";

type A = IsStringStrict<string>; // "yes"
type B = IsStringStrict<number>; // "no"
type C = IsStringStrict<string | number>; // "no" <- проверка по всему типу


Распределение происходит только при проверке «голого» T. Оборачивая T в [T], мы запрещаем TypeScript разбирать объединение и заставляем его проверять тип целиком.

🧩 Практический выбор:

✔️ Нужна логика для каждого члена union? — оставить поведение по умолчанию (распространение полезно);

✔️ Нужна единая проверка для всего типа? — спрятать T ([T] extends [...] ? ...) и получить один итоговый результат.

Как итог, осознание того, что условные типы по умолчанию работают с union поэлементно, а не целиком, заметно упрощает работу с типами. Приём с [T] позволяет явно задать намерение, а именно проверить весь тип сразу и избежать неожиданных объединений в результате. 👍
  • ❤ 10
  • 👍 8
  • 🔥 4
  • 😢 2
More from @katerina_profrontend
  1. Feb 22, 2026Когда height: 100% чуть-чуть поломало вёрстку 🙈 Я делала простую сетку: контейнер display…
  2. Feb 20, 2026Разбираемся с Proxy в JavaScript 👨‍🏫 Proxy — посредник между кодом и объектом. Он перехв…
  3. Feb 17, 2026Compression Streams API — нативный gzip/deflate прямо в браузере 🤔 Недавно снова вспомнил…
  4. Feb 9, 2026Почему бизнес-логику не стоит писать в UI-компонентах 🧐 Часто вижу один и тот же паттерн:…
  5. Feb 6, 2026Как неочевидные импорты превращают проект в клубок зависимостей 😨 На бумаге — простое пра…
  6. Feb 2, 2026«Хочу стиль для p в header, но не хочу повышать специфичность» 😎 Иногда самая тривиальная…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →