Практический TypeScript

Практический TypeScript

Практический TypeScript
Автор: Герасимов Александр
Дата выхода: 2025
Издательство: Самиздат
Количество страниц: 238
Размер файла: 2.7 MB
Тип файла: PDF
Добавил: codelibs
 Проверить на вирусы

Оглавление....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 с примерами и объяснениями на русском языке. Вместо длинных объяснений здесь собраны простые советы, правила и примеры.


Похожее:

Список отзывов:

Нет отзывов к книге.