Оглавление....2
📖 Быстрая навигация по разделам....2
🏗️ Основы TypeScript....2
🔧 Система типов....2
📝 Лучшие практики....3
🚀 Продвинутые типы....4
📦 Публикация и API....5
⚡ Производительность и миграция....5
📚 Справочные материалы....6
💡 Как использовать навигацию....6
Предисловие....6
Материалы охватывают основные темы TypeScript:....7
Для кого эта книга....7
Как использовать....7
Введение....7
Контакты....7
🏗️ Основы TypeScript (01-10)....9
Как TypeScript связан с JavaScript....9
🔷 Что такое JavaScript?....9
🔷 Что такое TypeScript?....9
🔁 Связь между TypeScript и JavaScript:....9
🔨 Как TypeScript работает?....10
📦 Как представить TypeScript?....10
Представь, что:....10
🧠 Важно запомнить:....10
Как Выбирать нужные опции в TypeScript....10
📁 Где вообще настраивается TypeScript?....11
🧭 Как выбирать нужные опции?....11
✅ 1. `strict: true` — строгий режим....11
🔍 2. `noImplicitAny: true` — запрет на неявный `any`....11
🔐 3. `strictNullChecks: true` — не смешивать `null` и другиетипы....11
🎯 4. `target: "ES6"` (или выше)....12
📦 5. `module: "commonjs"` или `"ESNext"`....12
📂 6. `rootDir` и `outDir`....12
📘 Другие полезные:....12
🚀 Советы по выбору:....12
🔧 Минимальный рекомендуемый `tsconfig.json`:....13
Генерация кода не зависит от типов....13
📌 Что это значит?....13
🧠 То есть: **типы — это как инструкция для разработчика икомпилятора**, но не для машины.....13
📦 Пример:....13
🧪 Почему это важно?....14
🧯 Что будет, если ты ошибся?....14
🧰 Если нужна проверка типа в рантайме....14
✨ Итог:....15
Что такое структурная типизация?....15
🧱 Что такое **структурная типизация**?....15
📦 Пример:....15
📛 В других языках (например, Java, C#) — **номинативнаятипизация**....16
🎯 Главное правило структурной типизации:....16
❗️ Из этого следуют плюсы и минусы:....16
✅ Плюсы:....16
❌ Минусы:....16
📌 Пример из жизни:....17
✨ Вывод:....17
Как ограничить тип any....17
📌 Почему `any` опасен?....17
✅ Способы ограничить или запретить `any`....18
1. **Включи строгий режим**....18
2. **`noImplicitAny: true`** — запрет неявного `any`....18
3. **`strictFunctionTypes: true`**....18
4. **Запретить `any` полностью — через линтер**....19
5. **Заменять `any` на более безопасные альтернативы**....19
`unknown` — безопасная альтернатива:....19
✨ Дополнительно:....19
🔚 Вывод:....20
Как использовать редактор дляполучения информации о системе типов....20
🛠 1. **Наведи мышку на переменную, функцию,тип**....20
💡 2. **Cmd (Mac) / Ctrl (Win) + Click** — перейти копределению....21
🔍 3. **F12** или **"Go to Definition"**....21
⌨️ 4. **TypeScript: Go to Type Definition**....21
💬 5. **Типовые подсказки при наведении**....21
🔁 6. **Проверка типа через `as const`, `typeof`,`satisfies`**....22
💥 7. **Проверка вывода типа: `type T = typeof x`**....22
🧪 Бонус: **Inline Type Explorer** (только вредакторе)....22
🧰 Что тебе нужно?....22
🔚 Итог: как изучать типы через редактор....23
Типы как множества значений....23
🧠 Идея: **тип = множество возможных значений**....23
📦 Примеры:....23
🔢 Примитивные типы....23
🧮 Объединения (Union) = объединение множеств....24
🚫 Пересечения (Intersection) = пересечение множеств....24
📜 Литеральные типы = конкретные значения....24
📐 Подтипы и расширение....24
🤔 Зачем это понимать?....25
🧪 Пример с проверкой:....25
✅ Вывод:....25
Как выражать принадлежностьсущностей к пространству типов илипространству значений....26
📌 Главное различие:....26
✅ Пространство **типов**:....26
✅ Пространство **значений**:....26
🚦 Как выразить принадлежность?....27
1. **К типам** — через `:` или `extends`....27
2. **К значениям** — через `typeof`, `instanceof`, `typeof x ==="..."`....27
🎯 Как не путать?....27
💡 Мнемоника:....28
🧪 Пример из жизни:....28
🧠 Advanced: только в пространстве типов....28
✅ Вывод....28
Как отдавать предпочтение аннотациямтипов, а не утверждениям....29
✅ **Аннотация типов (type annotation)** —правильно....29
⚠️ **Утверждение типов (type assertion)** —потенциально опасно....29
📌 Главное отличие:....30
🧠 Почему отдаём предпочтение **аннотациям**?....30
✅ 1. **Аннотации проверяются**....30
⚠️ А утверждение может обмануть:....30
✅ 2. **Аннотация документирует намерения**....30
✅ 3. **Работает с type inference**....30
🤯 Почему утверждения (`as`) — это костыль?....31
📎 Когда **можно использовать утверждение(`as`)**?....31
🔚 Вывод....31
Как и для чего избегать объектных типов-оберток (String, Number, Boolean, Symbol,BigInt)....31
🧱 1. Что такое "объектные обёртки"?....32
🚫 Почему **НЕ нужно использовать** обёртки?....32
⚠️ 1. Это не одно и то же!....32
⚠️ 2. Обёртки ломают строгую типизацию....32
⚠️ 3. Могут привести к странным багам....33
✅ Что использовать вместо них?....33
✅ Как писать правильно в TypeScript:....33
📌 Исключение: типы `Object`, `Function` и `{}`....34
🔍 Пример ошибки:....34
✅ Вывод....34
🔧 Система типов (11-30)....35
Проверка лишних свойств....35
📌 Главное различие:....35
🔍 Пример — **типовая проверка** (всё нормально)....35
🛑 Пример — **проверка лишних свойств**....35
📌 Правило:....36
✅ Как обойти (если нужно):....36
1. Вынести в переменную....36
2. Использовать оператор утверждения:....36
3. Указать "дополнительные свойства" в типе:....36
🧠 Почему TypeScript так делает?....36
🧪 Мини-сводка:....37
🧩 Вывод:....37
Как задать тип всему функциональномувыражению....37
✅ Цель: **типизировать всю функцию целиком**,а не только параметры или `return`.....37
🧠 Способы применять типы ко всемуфункциональному выражению:....38
✅ 1. **Через аннотацию переменной**....38
✅ 2. **Через `type` или `interface`**....38
✅ 3. **Анонимные функции с аннотацией**....38
✅ 4. **Стрелочная функция в типе функции высшего порядка**....38
⚠️ Антипаттерн: тип только у параметров....39
✍️ Советы:....39
✅ Пример: полная типизация....39
Различия между type и interface....40
🔹 Оба `interface` и `type` делают почти одно и тоже:....40
🔑 Но в чём же разница?....40
1. **Расширение (наследование)**....40
✅ `interface` легко **дополняется и объединяется**....40
⛔️ `type` так **не умеет**....41
2. **Композиция (соединение)**....41
`type` — мощнее в комбинировании....41
3. **Классы**....41
4. **Типы не только объектов**....41
🧠 Как запомнить:....42
Readonly в TypeScript....42
🔒 Что делает `readonly`?....42
🧱 Пример: `readonly` в объектах....42
🧩 Пример: `readonly` для массивов....43
🧰 Где `readonly` особенно полезен....43
✅ 1. Константные данные....43
✅ 2. Передача аргументов в функции....43
✅ 3. В Redux, Zustand и других хранилищах....44
🔁 Readonly утилиты....44
✋ Почему это важно?....44
🧠 Вывод....45
Сравнение с `const` и `Object.freeze()`....45
📚 Кратко: как они работают....45
🔍 Подробнее:....45
✅ 1. `const`....45
✅ 2. `readonly` (TS)....46
✅ 3. `Object.freeze()` (JS)....46
🔁 Как их сочетать....46
✅ Самое безопасное — вместе:....46
❗️ В чём подвох?....47
1. `readonly` — **не работает во время выполнения**....47
2. `Object.freeze()` — **не гарантирует типовую защиту**....47
📌 Итоговая таблица сравнения....47
💡 Рекомендация....47
Как использовать операции типов....48
🔧 Что такое операции над типами?....48
📦 Пример: избежать повторов с `Pick`....48
🧹 Пример: `Omit` для исключения....49
🧩 Пример: `Partial` и `Required`....49
📘 Обобщения (дженерики) для повторногоиспользования....49
🛠 Комбинирование: обобщения + операции надтипами....50
📌 Вывод....50
🎓 Пример для вдохновения....50
Используйте более точные альтернативыдля сигнатур индексов....51
🚫 Проблема с «широкой» индексной сигнатурой....51
✅ Альтернатива 1: Перечисление известныхключей....51
✅ Альтернатива 2: Использовать `Record`....52
✅ Альтернатива 3: Использовать объект сшаблонными ключами....52
✅ Альтернатива 4: Типы через Map/Set....52
⚖️ Сравнение подходов....52
📌 Вывод....53
Избегайте использования числовыхсигнатур индексов....53
🧱 Что такое числовая сигнатура индекса?....54
❌ Почему **не стоит** использовать `[index:number]`?....54
✅ Альтернатива 1: Использовать `string[]` или`Array`....54
✅ Альтернатива 2: Кортежи — для фиксированнойдлины....54
✅ Альтернатива 3: Объекты с ключами-числами(если нужны)....55
🧠 Совет: если нужна структура**массивоподобная**, используй массив (`Array`), ане `[index: number]: T`....55
📌 Итого....55
Не засорять код лишними аннотациямитипов....55
🧠 Правило: **Аннотируй там, где это нужно**, а невезде....56
✅ Где **не нужно** писать аннотацию — TypeScript самсправится:....56
Присваивание переменной....56
Возвращаемое значение из `map`, `filter`, `reduce` и т.п.....56
Функции с очевидным типом возвращаемого значения....56
✅ Где **стоит** писать аннотации....56
❌ Пример кода с лишними аннотациями (плохо)....57
📌 Совет....58
Используйте разные переменные дляразных типов....58
📌 В чём идея?....58
❌ Плохой пример — всё в одной переменной....58
✅ Хороший пример — отдельные переменные....59
💡 Где это особенно важно?....59
1. **Обработка разных данных**....59
2. **Работа с результатами API**....59
🚫 Почему не стоит делать так:....60
📋 Резюме....60
Что такое расширение типов в TypeScript....60
🧱 Что такое "расширение типов"?....61
✅ Пример: расширяем `User`....61
🧰 Два способа расширять типы....61
1. Через `extends` в интерфейсах....61
2. Через `&` (intersections) в `type`....62
🔄 Расширение с изменением типа....62
📐 Когда это нужно?....62
🧠 Важно помнить....62
📌 Резюме....63
Почему лучше создавать объектыцеликом....63
🧩 Что значит "создавать объект целиком"?....63
❌ Плохо — создаём объект по частям....63
🚨 Почему это плохо:....63
✅ Хорошо — создать объект сразу целиком....64
👍 Почему это хорошо:....64
🧠 Зачем это правило?....64
🛡️ А что если объект создаётся динамически?....64
💡 Совет: Не используй `as Type` для "достройки"объекта....64
✅ Можно использовать вспомогательные функции....65
🧪 Проверка лишних свойств тоже работает толькопри **целиком созданном объекте**....65
📌 Вывод....65
Сужение типов....66
📌 Что такое сужение типов?....66
📦 Пример: объединённый тип....66
🔧 Способы сужения типов....66
1. **`typeof` — для примитивов**....66
2. **`in` — для объектов с разными полями**....67
3. **Сравнение с `null`, `undefined`**....67
4. **`===` / `!==` — для литералов**....67
5. **Проверка через пользовательский `type guard`**....67
⚠️ Без сужения — плохо....68
🧠 Как освоить:....68
✅ Сужение = без `any`, без кастов (`as`), безошибок....68
Как быть последовательным сиспользованием псевдонимов....68
🧾 Что такое псевдонимы типов?....69
✅ Как быть последовательным — простыеправила....69
1. **Если начал использовать псевдонимы — используй ихвезде**....69
2. **Даём имена, отражающие смысл**....69
3. **Избегаем избыточности**....70
4. **Отделяй alias от интерфейсов**....70
5. **Пиши в одном стиле: либо `type`, либо `interface`, немешай без причины**....70
6. **Разделяй области: отдельные файлы/модули для типов**....71
📌 Резюме: как быть последовательным....71
Как использовать контекст при выводетипов....71
🧠 Что такое контекстный вывод типов?....71
📦 Примеры....72
✅ Пример 1. Callback в `.map`....72
✅ Пример 2. Обработчик события....72
✅ Пример 3. Функции как параметры....72
🚫 Пример, где контекста нет → нужен явный тип....72
🧠 Где работает контекстный вывод:....73
💡 Советы: как эффективно использовать....73
✅ Используй функции в контексте....73
✅ Не пиши типы, если контекст их даёт....73
❗️ Не полагайся на вывод, если:....74
📌 Резюме....74
Эволюционирующие типы....74
🧠 Что такое *эволюционирующий тип*?....74
🔍 Пример:....74
🧩 Другой пример: массив....75
❗️Почему это опасно?....75
✅ Как правильно:....75
1. **Сразу задавай явный тип**....75
2. **Используй `const` вместо `let`, если значение неизменяется**....75
3. **Для массивов указывай тип, даже если он пустой**....76
4. **Не полагайся на `let x;` без типа**....76
🔄 Типичная ловушка....76
📌 Резюме....76
Функциональные конструкции ибиблиотеки для улучшения работы стипами....77
🧠 Идея: типы и функции должны быть *связаны*....77
✅ Что значит "функциональные конструкции"?....77
📦 Примеры и как они улучшают типы....77
1. **Функции высшего порядка с типами**....77
2. **Функции-комбинаторы (`pipe`, `compose`)**....78
3. **Типизированные контейнеры: `Option`, `Either`**....78
4. **Pattern Matching (например, `ts-pattern`)**....78
📚 Полезные библиотеки....79
🎯 Как улучшает работу с типами?....79
💡 Советы....79
Async-функции вместо обратных вызовов....79
🔁 Что такое "обратный вызов" (callback)?....80
✅ Как использовать `async/await` вместо этого....80
🧠 Как это улучшает работу с типами....80
🧱 Как переделать код с callback → `async`....81
Было:....81
Стало:....81
🧯 Обработка ошибок....81
📌 Резюме....82
📚 Советы....82
Классы и каррирование для созданияновых точек вывода типов....82
🔎 Что такое "точка вывода типов"?....82
🧱 1. Классы как точка вывода....83
🔄 2. Каррирование как точка вывода....83
🔁 Пример: создать трансформатор с классом икаррированием....84
⚡️ Комбинация: каррированная функция-конструктор с классом....84
🧠 Зачем это нужно?....84
📌 Резюме....85
Моделирование допустимых состояний(valid states)....85
🧠 Цель:....85
✅ Принципы:....85
🔧 Пример: загрузка данных....85
❌ Неправильно (можно совместить несовместимое):....85
✅ Правильно (моделируем допустимые состояния явно):....86
🧱 Пример: формы....86
📌 Техника: \[**Tagged unions** / Discriminatedunions\*\*]....87
✨ Плюсы подхода....87
❗️ Не допускай таких состояний:....87
🧠 Подсказка: типы = множества допустимыхзначений....88
🔚 Резюме....88
Будь консервативным в отправке,либеральным в приёме....88
📌 Принцип:....88
🔧 На практике в TypeScript:....88
1. **Либеральный приём: принимать больше вариантов**....88
2. **Консервативная передача: возвращать минимальнодостаточное**....89
💡 Почему это важно?....89
✅ Пример хорошего баланса....89
🛑 Что не делать....90
❌ Не возвращай «тяжёлые» объекты:....90
🧠 Пример с типами:....90
📌 Итоговое правило:....90
📝 Лучшие практики (31-49)....91
Не повторять информацию типа вдокументации....91
🎯 Принцип....91
❌ Пример плохой практики....91
✅ Лучше так:....91
🔧 Когда писать документацию?....92
📌 Правило: "Объясняй поведение, не структуру"....92
🤖 Вместо комментариев — используйте мощныетипы....92
✨ Используй JSDoc там, где это нужно:....93
🧠 Вывод....93
Избегать включения null или undefined впсевдонимы типов....93
🔎 Что это значит?....93
❌ Почему это плохо?....93
✅ Что делать вместо этого....94
1. Разделяй "есть значение" и "нет значения"....94
2. Избегай включения `null | undefined` в сам тип....94
3. Будь явным в том, что `null` или `undefined` — часть логики....95
🧠 Пример из жизни....95
🔧 Резюме: как избегать `null` / `undefined` впсевдонимах....95
Вынесение null на периферию типов....95
🔎 Что значит "на периферию"?....96
📉 ❌ Плохо: `null`/`undefined` внутри сложныхтипов....96
📈 ✅ Хорошо: оборачивай всё в явно различимыеформы....96
📌 Подход: моделируй отсутствие целиком, а некусками....97
📌 "Периферия" — это:....97
🔧 Примеры на практике....97
❌ Внутри структуры:....97
✅ На уровне возвращаемого значения:....98
🧠 Зачем это делать?....98
💡 Совет....98
🧩 Хочешь пример "до и после"?....98
✅ Резюме: как выносить `null` на периферию....99
Предпочитай объединения интерфейсов(union of interfaces)....99
🧩 Принцип:....99
🤔 В чём разница?....99
❌ Интерфейс с объединением в поле:....100
✅ Объединение интерфейсов:....100
🧠 Почему это лучше?....100
📌 Запомни:....101
🔄 Как перейти с «интерфейса с объединениями»на объединения интерфейсов?....101
✅ Пример: API ответ....101
📌 Резюме....102
Использование более узких (строгих)типов вместо `string`....103
🔎 Почему просто `string` — не всегда хорошо?....103
✅ Как сделать лучше?....103
1. 🔐 Используй **литеральные типы**:....103
2. 🏷️ Используй **брендированные строки** (Branded types)....103
3. 🧩 Используй **шаблонные строковые типы**....104
4. 🗃️ Используй **enum** (если значения фиксированы и нужнычисла)....104
📌 Пример до и после....104
🧠 Резюме: как заменить `string`....105
Использовать отдельный тип дляспециальных значений....105
🧩 Что значит "специальные значения"?....105
❌ Плохо: использовать обычные значения....105
✅ Лучше: использовать отдельный тип....106
🔧 Ещё примеры....106
🧾 Пример 1: Специальное значение в результатах....106
💬 Пример 2: Статус загрузки....106
🛡️ Зачем это делать?....107
📌 Используй, когда…....107
🧠 Резюме....107
Ограничить использование опциональныхсвойств....108
🔍 Что значит "ограничить использованиеопциональных свойств"?....108
❗ Почему чрезмерное использование вредно?....108
✅ Как ограничивать опциональность?....108
1. **Предпочитай объединения типов с `kind` вместо `?`**....108
2. **Уточняй типы при построении**....109
3. **Или — используй `null`/`undefined` как значение, не какотсутствие**....109
4. **Строго описывай этапы создания объекта**....110
5. **Не делай поля опциональными, если они "появляютсяпозже"**....110
🧠 Резюме....111
Избегайте повторяющихся параметроводного типа....111
❌ Пример плохой практики....111
✅ Как избежать?....111
1. 📦 Объединяй параметры в объект с полями....111
2. 🧩 Используй именованные типы....112
3. 🔍 Используй **tuple only if order matters and types aredistinct**....112
4. 🧠 Типы с брендингом (если всё-таки нужно оставитьпозиционность)....112
🧠 Резюме....113
Унификация типов, вместо моделирования....113
🤔 Что это значит?....113
❌ Плохо: избыточное моделирование различий....113
✅ Лучше: **унифицированная форма**....114
📦 Пример из API....115
💡 Когда уместна унификация:....115
📌 Принцип....115
🧠 Резюме....116
Лучше неточно, чем недостоверно....116
📌 Что это значит?....116
❗ Недостоверный тип: опасно....116
✅ Неточный, но безопасный тип....117
🎯 Когда использовать более **неточный** тип....117
🧠 Пример: API-запрос....118
📌 Идея в одном предложении....118
🧠 Резюме....119
Имена типов на языке предметнойобласти задачи....119
🧠 Что это значит?....119
📌 Пример....119
❌ Плохо:....119
✅ Хорошо (на языке предметной области):....119
🛠 Как подбирать имена....120
📦 Пример из интернет-магазина....120
🤝 Зачем это нужно....121
📌 Полезный приём: "задать вопрос"....121
🧠 Резюме....121
Типы на основе API и спецификаций, а неданных....121
🔍 Что значит "генерировать типы поспецификации"?....122
❌ Плохо: типы по наблюдаемым данным....122
✅ Хорошо: типы из спецификации....122
🛠 Инструменты для генерации типов....123
🧠 Почему так важно?....123
🔁 Если спецификации нет?....123
📌 Резюме....124
Использовать максимально узкийдиапазон для типов any....124
🔥 Почему `any` опасен?....124
✅ Как использовать `any` максимально безопасно....125
1. **Ограничь область действия `any` одной переменной**....125
2. **Сужай `any` как можно скорее**....125
3. **Не распространяй `any` в другие типы**....125
4. **Используй `unknown` вместо `any`**....126
5. **Ставь `any` только в точках, где *другого выхода нет***....126
6. **Оборачивай `any`-объекты в валидаторы**....126
🧠 Резюме: как ограничивать `any`....127
Более точные варианты any....127
🛡 Почему не `any`?....127
✅ Альтернативы `any` — с пояснениями....127
❌ Чего избегать....128
🔍 Примеры....128
1. `unknown` вместо `any`....128
2. `Record` вместо `any`....128
3. `Partial` — частично известная структура....129
4. Уточнение сигнатуры функции....129
5. Обёртка с `zod` (или другим валидатором)....129
🧠 Резюме....130
Скрывать небезопасные утверждениятипов в хорошо типизированных функциях....130
🎯 Цель....130
✅ Как это делать правильно....130
1. **Упаковывай небезопасность в маленькие, строготипизированные функции**....131
2. **Пиши обёртки с валидаторами**....131
3. **Скрывай `as` внутри утилит**....132
4. **Сужай `any` и `unknown` до строго определённых типов**....132
5. **Документируй риск, если избежать `as` невозможно**....132
🧠 Резюме....133
unknown вместо any для значений снеизвестным типом....133
🤔 Почему `unknown` лучше, чем `any`?....133
✅ Как использовать `unknown` правильно?....133
1. Объявляй переменные или аргументы как `unknown`, если незнаешь тип заранее....134
2. Используй проверки типов перед использованием....134
3. Используй пользовательские функции-утверждения (typeguards)....134
4. Используй библиотеки для валидации (`zod`, `io-ts`, `valibot`и т.д.)....134
5. Никогда не делай так:....135
🧠 Резюме....135
Типобезопасные решения вместодинамической модификации....135
🚫 Примеры динамической модификации (плохо вTypeScript)....136
✅ Альтернативы — типобезопасные подходы....136
1. **Явное создание объектов (сразу целиком)**....136
2. **Чистые функции для изменения объектов (без мутаций)**....136
3. **Mapped types + Record для предсказуемых структур**....136
4. **Функции обновления с типами ключей**....137
5. **Удаление свойств — через утилиты или строгие обёртки**....137
🧠 Резюме....137
Избегайте ловушек надежности....137
🕳️ Что такое "ловушки надёжности"?....138
🔥 Примеры ловушек и как их избегать....138
1. **Использование `any`**....138
2. **Тип `{} ` (пустой объект)**....138
3. **Объектные типы-обёртки (`String`, `Number`, `Boolean`)**....138
4. **Избыточная уверенность через `!` (non-null assertion)**....139
5. **Слепое утверждение типов (`as T`) без проверки**....139
6. **Опциональные поля без проверки**....139
✅ Общие советы, чтобы не попасть в ловушку....140
Отслеживайте зону охвата типов дляпредотвращения регрессии втипобезопасности....140
💡 Что такое "зона охвата типов"?....140
✅ Как отслеживать и поддерживать типовую зонуохвата?....141
1. **Включи строгий режим (`strict`)**....141
2. **Избегай `any` и замени их на `unknown`, `never`, `T`,`Partial`, и т.д.**....142
3. **Запрещай `any` через `tsconfig`**....142
4. **Интегрируй линтер (ESLint + TypeScript)**....142
5. **Проверяй границы зон: где типы «теряются»**....142
6. **Пиши больше *type-safe* утилит вместо дублирования**....143
7. **Автоматизируй проверку охвата**....143
🧠 Резюме: как удерживать границытипобезопасности....143
🚀 Продвинутые типы (50-64)....144
Обобщённые (generics) конструкции....144
📌 Простой пример....144
📦 Где рассматривать обобщения в практике....144
🧠 Примеры «обобщённого мышления» в типах....145
1. Обобщённая функция фильтра....145
2. Обобщённый тип ответа API....145
3. Обобщённый компонент в React....145
✅ Зачем рассматривать обобщения?....146
Избегайте лишних параметров типа....146
📌 В чём проблема с лишними тип-параметрами?....146
❌ Пример лишнего параметра....146
🛠️ Как распознать и избежать лишнего параметра....147
✅ Правило 1: Убирай параметр, если его можно вывести....147
✅ Правило 2: Если параметр никогда не ограничивается — онне нужен....147
✅ Правило 3: Используй `extends` и `keyof` для ограниченияобобщения....147
✅ Правило 4: Заменяй одиночные `T` на конкретные типы,если они не должны быть обобщёнными....148
✅ Правило 5: Используй TypeScript-инференс максимально....148
🧠 Кратко....148
Лучше условные типы, чемперегруженные сигнатуры....148
📌 Что такое перегруженные сигнатуры?....149
✅ Вместо этого — используем **условный тип** (`Textends X ? A : B`):....149
🧠 Почему это лучше?....150
📌 Пример: вместо перегрузок....150
❌ Так не надо:....150
✅ Лучше так:....150
💡 Когда перегрузки всё же полезны?....150
Распределение объединений....150
📦 Что такое **распределение объединений**?....151
🧠 TypeScript распределяет объединение:....151
✅ Как **управлять распределением**?....151
📌 1. **Распределение включено по умолчанию**....151
📌 2. **Отключить распределение вручную** — оберни `T` вкортеж `[T]`....151
🛠️ Когда нужно включать или отключать?....152
✅ Распределять — когда нужно **отдельно обработатькаждый тип**:....152
❌ Не распределять — когда нужно **принять только точныйтип**:....152
🧠 Резюме....152
Шаблонные литеральные типы длямоделирования DSL и отношений междустроками....153
🧩 **Шаблонные литеральные типы в TypeScript**....153
📌 Зачем они нужны?....153
🔧 Синтаксис....153
✅ Примеры использования....153
✅ 1. **Моделирование API DSL**....153
✅ 2. **Маппинг из имени в ключ (CSS, HTML, конфиги, и т.п.)**....154
✅ 3. **Типизация строк-команд в DSL**....154
✅ 4. **Отношения между типами строк**....154
✅ 5. **Ключи объектов по шаблону**....154
🧠 Советы....155
🔍 Проверка формата строки....155
🛠 Пример: генерация сообщений ошибок....155
🔗 Когда это особенно полезно....156
Как писать тесты для типов....156
📌 Способы тестирования типов....156
✅ 1. **С помощью утилит компилятора (`@ts-expect-error`,`@ts-ignore`, `satisfies`, и др.)**....156
✅ Пример: проверить, что тип сужается корректно....156
✅ 2. **С помощью `satisfies`**....156
✅ 3. **Использовать библиотеки для типовых тестов**....157
🧪 Библиотека [`tsd`](https://github.com/SamVerschueren/tsd)....157
🧪 Альтернатива: [`type-plus`](https://github.com/unional/type-plus)....157
🧠 Самодельные проверки через условные типы....157
🧪 Где писать типовые тесты?....157
✅ Резюме....158
Обращайте внимание на отображениетипов....158
🔍 Следите за тем, **как вы преобразуете исоздаёте новые типы** на основе других —особенно с помощью **mapped types**(отображаемых типов).....158
🔧 Что такое "отображение типов"?....158
🎯 Зачем **обращать внимание**?....159
📌 Примеры, где это важно....159
✅ 1. Добавляем модификаторы аккуратно....159
✅ 2. Убираем модификаторы....159
✅ 3. Генерируем новые ключи....159
⚠️ Опасность: не потеряй информацию....160
🧠 Вывод....160
Отдавайте предпочтение обобщеннымтипам с хвостовой рекурсией....160
📘 Что это значит?....160
📌 Пример: рекурсивный тип БЕЗ хвостовойрекурсии....161
✅ Пример: тот же тип С ХВОСТОВОЙ РЕКУРСИЕЙ(Tail Recursion)....161
🤔 Почему это важно?....161
🎯 Когда использовать?....161
✅ Пример — `Join<['a', 'b', 'c'], '-'>`....162
🧠 Вывод....162
Кодогенерация как альтернативасложным типам....162
📌 Почему это важно....163
🧠 Примеры ситуаций, когда стоит подумать о**кодогенерации**....163
✅ Альтернативы: инструменты кодогенерации....163
🛠️ Пример: собственная генерация типов....163
🎯 Преимущества кодогенерации....164
⚠️ Недостатки....164
💡 Когда **точно** лучше использоватькодогенерацию:....164
✅ Заключение....165
Типы never для выполнения проверкиполноты....165
🔍 Что значит "проверка полноты"?....165
📌 Пример: дискретное объединение....165
✅ Проверка с помощью `never`....165
🔒 Как это работает:....166
✅ То же самое с `if/else`....166
🎯 Зачем это нужно?....166
⚠️ Частая ошибка: `default` без `never`....167
💡 Функция для проверки....167
📌 Вывод....167
Итерация по объектам....167
🛠 Базовые способы итерации....167
1. `for...in` — по ключам....168
2. `Object.entries`....168
3. `Object.keys`....168
📦 Объект с известной структурой....169
🧠 Итерирование по объекту с динамическимиключами....169
🎯 Полезные типы и утилиты....170
✅ Рекомендации....170
Типы записей для поддержаниясинхронизации значений....170
📌 Синтаксис `Record`....170
🧠 Применение: синхронизация значений....171
1. 💬 Сопоставление ключей и значений....171
2. ⚙️ Перечисление enum → значения....171
3. ✅ Связывание типов ключей и значений....172
4. 📄 Форма или конфиг как типизированная таблица....172
💡 Почему `Record` помогает держать значениясинхронизированными?....172
🎯 Заключение....173
Остаточные параметры и типы кортежадля моделирования функций спеременным числом аргументов....173
📌 Пример 1: Простая функция с переменнымчислом аргументов....173
📦 Пример 2: Типизация кортежей....173
🎯 Пример 3: Дженерик с кортежем....174
🔄 Пример 4: Перегрузка через условный кортеж....174
🧠 Пример 5: Частичное применение(каррирование)....175
✅ Когда использовать....175
📌 Вывод....175
Используйте опциональные свойстваnever для моделирования исключающегоИЛИ....176
📌 Что такое исключающее ИЛИ (XOR)?....176
🚫 Почему обычный `A | B` не всегда работает?....176
✅ Решение: опциональные свойства `never`....176
🔧 XOR через утилиту:....176
Пример:....177
📘 Как это работает?....177
🎯 Когда использовать?....177
📌 Вывод....177
Маркировки для номинальной типизации....178
📘 Что такое номинальная типизация?....178
✅ Решение: маркировка через `& { __brand: '...' }`....178
🧰 Как создать безопасно?....179
🎯 Где применяют?....179
🧠 Почему это работает?....179
📌 Вывод....179
📦 Публикация и API (65-71)....180
Размещать TypeScript и @types вdevDependencies....180
✅ Краткий ответ....180
📦 Что такое `devDependencies`?....180
🎯 Почему `typescript` — это devDependency?....180
📦 Почему `@types/...` — это devDependency?....181
❌ Почему **не стоит** помещать в `dependencies`....181
🧠 Исключения....181
✅ Вывод....181
Проверять совместимость трех версий,задействованных в объявлениях типов....182
🧩 Что за «три версии»?....182
🎯 Почему это важно?....182
📌 Пример проблемы....182
✅ Как правильно проверять совместимость....183
1. 📦 Убедитесь, что версия `@types/...` подходит длябиблиотеки....183
2. 🧪 Убедитесь, что `@types/...` совместимы с вашей версиейTypeScript....183
3. 🔧 Заблокируйте версии в `package.json`....183
🧰 Совет: настройка `package-lock.json` или `pnpm-lock.yaml`....184
🧠 Вывод....184
Экспортировать все типы, которыепоявляются в открытом (публичном) API....184
📌 Цель....184
✅ Что значит «открытый API»?....184
🧱 Пример: библиотека или модуль....185
💡 Надо экспортировать и `AddOptions`!....185
🚨 Почему это важно....185
🧰 Практика: `index.ts` как точка входа....186
🛠 Автоматизация (по желанию)....186
📦 При создании библиотеки (npm-пакета)....186
Важно:....186
🔁 Повторим правило....186
✅ Чеклист....187
TSDoc для комментариев к API....187
✍️ Что такое TSDoc?....187
📘 Базовый синтаксис....187
🧠 Куда писать комментарии?....187
🛠 Основные теги TSDoc....188
📦 Пример для интерфейса....188
🧪 Пример с `@example`....189
⚠️ Важно....189
🔧 Инструменты, совместимые с TSDoc....189
📁 Структура хорошей документации....189
✅ Резюме....190
Определять тип this в обратных вызовах,если он является частью API....190
🔧 Как указать тип `this` в функциях....190
✅ Пример:....190
❌ Почему нельзя использовать стрелочныефункции?....191
⚙️ Сигнатура с `this` в типе функции....191
🧠 Куда это нужно?....192
📦 Бонус: использование `bind`....192
✅ Вывод....192
Зеркалирование типов для разрывазависимостей....192
🪞 Что значит "зеркалировать типы"?....193
🔧 Как это выглядит на практике?....193
🎯 Цель: отделить типы от реализации....193
🧠 Трюк: зеркалировать через `typeof`....194
🛠 Альтернативы через маппинг....194
📦 Пример для DTO/API....194
🧩 Когда это полезно?....195
✅ Советы....195
Аугментацию модулей для улучшениятипов....195
🔧 Пример: Расширение типов `express.Request`....195
💡 Важно:....196
🧩 Пример с собственным модулем....196
🛠 Частый паттерн: расширение глобальныхинтерфейсов....197
📦 Где применяется:....197
✅ Советы:....197
⚡ Производительность и миграция (72-83)....198
Отдавать предпочтениефункциональности ECMAScript передTypeScript....198
🧠 Почему?....198
📌 Примеры....198
✅ Используйте `Array.prototype.map` вместо собственныхутилит с типами:....198
✅ Используйте `Record` или `Map` вместо своей типовойструктуры:....199
✅ Используйте `as const` вместо избыточных enum:....199
🔍 Общая идея....199
💬 Когда стоит использовать TypeScript-функциональность?....200
✅ Вывод....200
Source Map для отладки TypeScript....200
🧩 Что такое Source Map?....200
🛠 Как включить Source Map....200
🧪 Как использовать Source Map в браузере(например, Chrome DevTools)....201
🧠 Пример....201
🛡 Полезно для:....202
🧯 Частые проблемы....202
✅ Вывод....202
Реконструкция типов на стадиивыполнения....202
🧠 Главный принцип:....203
✅ Способы реконструкции типов....203
1. 📦 Использование библиотек валидации + типизация....203
2. 🧪 Ручная проверка структуры объектов....203
3. 🧩 Использование декораторов + Reflect Metadata....204
🔄 Идея: тип → схема → валидация → тип....204
📌 Когда нужно реконструировать тип?....205
📦 Рекомендуемые библиотеки....205
🏁 Вывод....205
Иерархия DOM (Document Object Model)....205
🧱 Что такое DOM в контексте TypeScript?....205
🧭 Как получить доступ к DOM-элементам....206
🔹 Способы доступа:....206
🔹 Проверка на null:....206
🔹 Или через non-null assertion (используй осторожно!):....206
🔍 Как работает иерархия DOM в типах....206
Пример:....206
🛠 Работа с детьми, родителями, и соседями....207
🔁 Пример: обход DOM-дерева с типами....207
✅ Типы элементов....207
⚠️ Что важно:....208
🧪 Пример: безопасное взаимодействие с формой....208
💡 Заключение....208
Точная модель среды выполнения....208
🧭 Зачем это нужно?....209
🔧 Шаги по созданию точной модели средывыполнения....209
1. **Опиши ожидаемую структуру данных в типах**....209
2. **Проверь данные на соответствие типу (валидация)**....209
✅ Либо собственную проверку:....209
✅ Либо использовать библиотеку валидации с выводом типов:....209
3. **Моделируй API/систему строго**....210
4. **Сопровождай типы runtime-валидацией**....210
5. **Не полагайся на типы для сторонних данных**....210
6. **Учитывай платформенные особенности**....211
✅ Краткий чеклист: точная модель среды....211
💬 Если коротко....211
Проверка типов и юнит-тестирование....211
🧠 В чём разница?....211
🔗 Как они связаны?....212
1. **Типы → Меньше необходимости в тестах на формыданных**....212
2. **Типы помогают писать тесты**....212
3. **Типы ≠ поведение**....212
4. **Типы могут "подсказывать" тест-кейсы**....213
🛠 Лучшее использование — вместе....213
📌 Вывод....213
Быстродействие компилятора....213
🚀 Кратко: как ускорить компиляцию TypeScript....214
📁 1. Разделение на проекты (`Project References`)....214
⚙️ 2. Настрой `tsconfig.json` для скорости....214
🧠 3. Избегай сложных и дорогих для проверкитипов....215
👀 4. Используй флаг `--watch` и `--incremental`....215
📊 5. Включи `--diagnostics` для анализа....215
🧹 6. Удали неиспользуемые декларации....216
🧰 Инструменты для быстродействия....216
✅ Вывод....216
Использовать современный JavaScript....217
🚀 1. Используй ES6+ синтаксис....217
📦 2. Работай с асинхронностью через`async/await`....218
🛠 3. Используй современные коллекции....218
🧼 4. Пиши декларативно....218
📚 5. Придерживайся хорошего стиля....218
💡 6. Используй новые фичи стандарта(ECMAScript)....218
🔐 7. Избегай старого и небезопасного....219
⚙️ 8. Автоматизируй сборку и трансформации....219
🧪 9. Покрывай код тестами....219
🧠 10. Пиши с оглядкой на TypeScript....219
✨ Хочешь краткую памятку? Вот:....219
📦 ECMAScript-модули (ESM)....220
✅ Как экспортировать....220
✅ Как импортировать....220
✅ Экспорт по умолчанию....220
🏗️ Классы вместо прототипов....221
✅ Современный синтаксис: `class`....221
Наследование:....221
Почему это важно?....221
🧠 TL;DR....222
@ts-check и JSDoc в TypeScript....222
✅ Что такое `@ts-check`?....222
✅ Что такое JSDoc?....222
✍️ Примеры аннотаций с JSDoc....223
📌 Типизация переменной....223
📌 Массивы....223
📌 Объекты....223
📌 Обобщения (дженерики)....223
📦 Как включить поддержку `@ts-check` в проекте....223
🤓 Рекомендации....224
💡 Пример с `@typedef`....224
✅ Когда это полезно....224
allowJs для совмещения TypeScript иJavaScript....225
✅ Как включить `allowJs`....225
🧩 Разница между `allowJs` и `checkJs`....225
🧪 Пример смешанного кода....225
🛠️ Дополнительные советы....226
🧠 TL;DR....226
Конвертируйте модуль за модулем вверхпо графу зависимостей....227
🧠 Что такое граф зависимостей?....227
📈 Что значит «вверх»?....227
🧩 Почему это работает?....227
✅ Пример пошаговой миграции....228
🔁 Итог....228
Не считайте миграцию завершенной, покане включите noImplicitAny....228
Что такое `noImplicitAny`?....228
Почему это важно?....228
Как выглядит ошибка без `noImplicitAny`....229
Когда включать `noImplicitAny`?....229
Итого....229
📚 Справочные материалы....230
Базовые типы....230
✅ Примеры:....230
🧊 Особенности....230
1. `string` и `String` — не одно и то же....230
2. `null` и `undefined` — по умолчанию запрещены, если неуказаны явно:....231
3. Литеральные типы....231
🧠 TypeScript добавляет смысл....231
📌 Резюме....232
Дженерики....232
🔹 Зачем нужны дженерики?....232
🔹 Примеры использования....233
1. Функция с дженериком....233
2. Работа с массивами....233
3. Ограничения (`extends`)....233
4. Дженерики в интерфейсах....233
5. Дженерики в классах....234
6. Дженерики с несколькими параметрами....234
✅ Синтаксис:....234
🔧 Пример 1: преобразование объекта....235
🔧 Пример 2: асинхронная функция....235
🔧 Пример 3: тип функции....235
⚙️ А если `P` зависит от `T`?....235
📌 Резюме....236
🔹 Итог....236
Cпециальные типы....236
Основные специальные типы:....236
🔍 Подробнее с примерами....237
1. `any`....237
2. `unknown`....237
3. `never`....237
4. `void`....238
📌 Когда что использовать....238
Эта книга — для тех кто уже знаком с javascript, короткое и понятное практическое руководство по TypeScript с примерами и объяснениями на русском языке. Вместо длинных объяснений здесь собраны простые советы, правила и примеры.