Все думали, что TypeScript — ещё один корпоративный геморрой: способ Microsoft приковать девелоперов к многословному коду. Знаете, тот тип штук, что VC пиарят, пока кодеры скрипят зубами над optional и any. Но эти TypeScript-фишки, за которыми я хватаюсь ежедневно? Они меняют правила игры. Типы перестают мешать — теперь они тянут за вас тяжёлую ношу, отсекают баги, не раздувая кодбейс до размеров романа.
Двадцать лет я гоняюсь за силиконовыми игрушками — от пузыря Java-апплетов до сегодняшних ИИ-галлюцинаций. TypeScript? Не революция. Эволюция. Тихая, прагматичная. Та, что задаёт правильный вопрос: кто на деле быстрее шлёт в прод?
«Пишу на TypeScript уже несколько лет — для React Native, Node.js и кучи разных продуктов. И разрыв между тем, что учат доки, и тем, за чем тянешься ежедневно, огромный».
В точку. Доки толкают азы. Реальность требует вот этого.
Discriminated unions: Прощайтесь с optional-undefined-танцами
Слушайте.
Управление состоянием в приложухах — загрузка юзеров, постов, чего угодно — раньше означало везде data?.foo?.bar. Утомительно. Ошибочно.
Discriminated unions решают это на раз. Метите каждое состояние литералом status — и TypeScript сужает типы как лазером. Вот шаблон, который я копипащу в каждый проект:
type RequestState =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: User }
| { status: "error"; message: string };
Теперь в switch или if: if (state.status === 'success') { state.data.name } — никаких проверок на undefined. IntelliSense оживает. Баги испаряются.
Ничего нового — рустовские девы годы ржали над нами, JS-шниками, без этого. Но в мире TypeScript? Половина runtime-ошибок в нокауте. React Query и Zustand-фанаты кивают.
Мой циничный взгляд: Microsoft не изобрела это — просто сделала удобным для лентяев вроде меня. Выигрывают те, у кого меньше GitHub-иссу.
Почему ‘satisfies’ бьёт прямые аннотации наголову
Новичок на районе. satisfies. Неброский. Мощный.
Старый способ: const config: Record<string, string> = { theme: 'dark', language: 'en' };. Норм, но потом забудь про вывод 'dark' или 'en'. TypeScript расширяет до string. Бесит при чейнинге.
Входит satisfies:
const config = {
theme: "dark",
language: "en",
} satisfies Record<string, string>;
Типы проверены. Литералы сохранены. Волшебство.
Юзаю для конфигов, моков, тестовых данных. Чейнинг? config.theme === 'dark' ? darkMode() : lightMode(); — полный автокомплит. Никаких «ой, это же просто string».
Скептик во мне: почему не с первого дня? TypeScript 4.9 выкатили в 2022-м, а половина туториалов молчит. Классика — инструменты отстают от практики.
Утилитарные типы: Pick, Omit и чейнинг как профи
Partial и Required? Детский сад.
Настоящая работа: Pick, Omit, вложенные комбо.
// Вырезаем для превью
type Preview = Pick<Article, "title" | "slug" | "createdAt">;
// Убираем секреты для API
type PublicUser = Omit<User, "password" | "token">;
// Апдейты? Partial только на нужном
type UpdateInput = Partial<Pick<User, "name" | "bio"> & { email?: string }>;
PublicUser отдаёт клиенту без хэшей. Preview кормит списки без балласта. UpdateInput? Валидирует только изменения — никаких полных User на PATCH.
Чейнинг? Тёмное искусство. Сначала кажется хаком, но через пять лет — мышечная память. Экономит часы на рефакторинге API.
Денежный угол: enterprise в восторге. Легче бандлы, безопаснее пэйлоады. Счёта Azure тают. Satya Nadella спит спокойнее.
Стоит ли оператор ‘satisfies’ в TypeScript хайпа?
Коротко: да.
Хайп? Twitter перегибает. Не перепишет твой апп. Это 1% твиков, что накапливаются в 10x продуктивности. С unions — убийца для хуков: const [state, setState] = useState<RequestState>({status: 'idle'});. Без дриллинга пропсов.
Исторический параллель: PropTypes в React 1.0? Громоздкие. Flow попробовал — пр