Причиной многих программных ошибок становится несоответствие типов данных. Сильная система типов позволяет избежать целого класса ошибок и обеспечить целостность данных в рамках всего приложения. Разработчик, научившись мастерски использовать типы в повседневной практике, будет создавать более качественный код, а также сэкономит время, которое потребовалось бы для выискивания каверзных ошибок, связанных с данными.
В книге рассказывается, как с помощью типизации создавать программное обеспечение, которое не только было бы безопасным и работало без сбоев, но также обеспечивало простоту в сопровождении.
Примеры решения задач, написанные на TypeScript, помогут развить ваши навыки работы с типами, начиная от простых типов данных и заканчивая более сложными понятиями, такими как функторы и монады.
Author(s): Влад Ришкуция
Series: Библиотека программиста
Edition: 1
Publisher: Питер
Year: 2021
Language: Russian
Commentary: Vector PDF
Pages: 352
City: СПб.
Tags: Algorithms; JavaScript; Functional Programming; Object-Oriented Programming; Algebraic Data Types; TypeScript; Type Inference; Type Safety
Предисловие
Благодарности
О книге
Целевая аудитория
Структура издания
О коде
Об авторе
Дискуссионный форум книги
Об иллюстрации на обложке
От издательства
Глава 1. Введение в типизацию
1.1. Для кого эта книга
1.2. Для чего существуют типы
1.2.1. Нули и единицы
1.2.2. Что такое типы и их системы
1.3. Преимущества систем типов
1.3.1. Корректность
1.3.2. Неизменяемость
1.3.3. Инкапсуляция
1.3.4. Компонуемость
1.3.5. Читабельность
1.4. Разновидности систем типов
1.4.1. Динамическая и статическая типизация
1.4.2. Слабая и сильная типизации
1.4.3. Вывод типов
1.5. В этой книге
Резюме
Глава 2. Базовые типы данных
2.1. Проектирование функций, не возвращающих значений
2.1.1. Пустой тип
2.1.2. Единичный тип
2.1.3. Упражнения
2.2. Булева логика и сокращенные схемы вычисления
2.2.1. Булевы выражения
2.2.2. Схемы сокращенного вычисления
2.2.3. Упражнение
2.3. Распространенные ловушки числовых типов данных
2.3.1. Целочисленные типы данных и переполнение
2.3.2. Типы с плавающей точкой и округление
2.3.3. Произвольно большие числа
2.3.4. Упражнения
2.4. Кодирование текста
2.4.1. Разбиение текста
2.4.2. Кодировки
2.4.3. Библиотеки кодирования
2.4.4. Упражнения
2.5. Создание структур данных на основе массивов и ссылок
2.5.1. Массивы фиксированной длины
2.5.2. Ссылки
2.5.3. Эффективная реализация списков
2.5.4. Бинарные деревья
2.5.5. Ассоциативные массивы
2.5.6. Соотношения выгод и потерь различных реализаций
2.5.7. Упражнение
2.6. Резюме
2.7. Ответы на упражнения
Глава 3. Составные типы данных
3.1. Составные типы данных
3.1.1. Кортежи
3.1.2. Указание смыслового содержания
3.1.3. Сохранение инвариантов
3.1.4. Упражнение
3.2. Выражаем строгую дизъюнкцию с помощью типов данных
3.2.1. Перечисляемые типы
3.2.2. Опциональные типы данных
3.2.3. Результат или сообщение об ошибке
3.2.4. Вариантные типы данных
3.2.5. Упражнения
3.3. Паттерн проектирования «Посетитель»
3.3.1. «Наивная» реализация
3.3.2. Использование паттерна «Посетитель»
3.3.3. Посетитель-вариант
3.3.4. Упражнение
3.4. Алгебраические типы данных
3.4.1. Типы-произведения
3.4.2. Типы-суммы
3.4.3. Упражнения
3.5. Резюме
3.6. Ответы на упражнения
Глава 4. Типобезопасность
4.1. Избегаем одержимости простыми типами данных, чтобы исключить неправильное толкование значений
4.1.1. Аппарат Mars Climate Orbiter
4.1.2. Антипаттерн одержимости простыми типами данных
4.1.3. Упражнение
4.2. Обеспечиваем соблюдение ограничений
4.2.1. Обеспечиваем соблюдение ограничений с помощью конструктора
4.2.2. Обеспечиваем соблюдение ограничений с помощью фабрики
4.2.3. Упражнение
4.3. Добавляем информацию о типе
4.3.1. Приведение типов
4.3.2. Отслеживание типов вне системы типов
4.3.3. Распространенные разновидности приведения типов
4.3.4. Упражнения
4.4. Скрываем и восстанавливаем информацию о типе
4.4.1. Неоднородные коллекции
4.4.2. Сериализация
4.4.3. Упражнения
4.5. Резюме
4.6. Ответы на упражнения
Глава 5. Функциональные типы данных
5.1. Простой паттерн «Стратегия»
5.1.1. Функциональная стратегия
5.1.2. Типизация функций
5.1.3. Реализации паттерна «Стратегия»
5.1.4. Полноправные функции
5.1.5. Упражнения
5.2. Конечные автоматы без операторов switch
5.2.1. Предварительная версия «Программируй/Типизируй»
5.2.2. Конечные автоматы
5.2.3. Краткое резюме реализации конечного автомата
5.2.4. Упражнения
5.3. Избегаем ресурсоемких вычислений с помощью отложенных значений
5.3.1. Лямбда-выражения
5.3.2. Упражнение
5.4. Использование операций map, filter и reduce
5.4.1. Операция map()
5.4.2. Операция filter()
5.4.3. Операция reduce()
5.4.4. Библиотечная поддержка
5.4.5. Упражнения
5.5. Функциональное программирование
5.6. Резюме
5.7. Ответы на упражнения
Глава 6. Расширенные возможности применения функциональных типов данных
6.1. Простой паттерн проектирования «Декоратор»
6.1.1. Функциональный декоратор
6.1.2. Реализации декоратора
6.1.3. Замыкания
6.1.4. Упражнение
6.2. Реализация счетчика
6.2.1. Объектно-ориентированный счетчик
6.2.2. Функциональный счетчик
6.2.3. Возобновляемый счетчик
6.2.4. Краткое резюме реализаций счетчика
6.2.5. Упражнения
6.3. Асинхронное выполнение длительных операций
6.3.1. Синхронная реализация
6.3.2. Асинхронное выполнение: функции обратного вызова
6.3.3. Модели асинхронного выполнения
6.3.4. Краткое резюме асинхронных функций
6.3.5. Упражнения
6.4. Упрощаем асинхронный код
6.4.1. Сцепление промисов
6.4.2. Создание промисов
6.4.3. И еще о промисах
6.4.4. async/await
6.4.5. Краткое резюме понятного асинхронного кода
6.4.6. Упражнения
6.5. Резюме
6.6. Ответы на упражнения
Глава 7. Подтипизация
7.1. Различаем схожие типы в TypeScript
7.1.1. Достоинства и недостатки номинативной и структурной подтипизации
7.1.2. Моделирование номинативной подтипизации в TypeScript
7.1.3. Упражнения
7.2. Присваиваем что угодно, присваиваем чему угодно
7.2.1. Безопасная десериализация
7.2.2. Значения на случай ошибки
7.2.3. Краткое резюме высших и низших типов
7.2.4. Упражнения
7.3. Допустимые подстановки
7.3.1. Подтипизация и типы-суммы
7.3.2. Подтипизация и коллекции
7.3.3. Подтипизация и возвращаемые типы функций
7.3.4. Подтипизация и функциональные типы аргументов
7.2.5. Краткое резюме вариантности
7.3.6. Упражнения
7.4. Резюме
7.5. Ответы на упражнения
Глава 8. Элементы объектно-ориентированного программирования
8.1. Описание контрактов с помощью интерфейсов
8.1.1. Упражнения
8.2. Наследование данных и поведения
8.2.1. Эмпирическое правило is-a
8.2.2. Моделирование иерархии
8.2.3. Параметризация поведения выражений
8.2.4. Упражнения
8.3. Композиция данных и поведения
8.3.1. Эмпирическое правило has-a
8.3.2. Композитные классы
8.3.3. Реализация паттерна проектирования Адаптер
8.3.4. Упражнения
8.4. Расширение данных и вариантов поведения
8.4.1. Расширение вариантов поведения с помощью композиции
8.4.2. Расширение поведения с помощью примесей
8.4.3. Примеси в TypeScript
8.4.4. Упражнение
8.5. Альтернативы чисто объектно-ориентированному коду
8.5.1. Типы-суммы
8.5.2. Функциональное программирование
8.5.3. Обобщенное программирование
8.6. Резюме
8.7. Ответы на упражнения
Глава 9. Обобщенные структуры данных
9.1. Расцепление элементов функциональности
9.1.1. Повторно используемая тождественная функция
9.1.2. Тип данных Optional
9.1.3. Обобщенные типы данных
9.1.4. Упражнения
9.2. Обобщенное размещение данных
9.2.1. Обобщенные структуры данных
9.2.2. Что такое структура данных?
9.2.3. Упражнения
9.3. Обход произвольной структуры данных
9.3.1. Использование итераторов
9.3.2. Делаем код итераций потоковым
9.3.3. Краткое резюме по итераторам
9.3.4. Упражнения
9.4. Потоковая обработка данных
9.4.1. Конвейеры обработки
9.4.2. Упражнения
9.5. Резюме
9.6. Ответы на упражнения
Глава 10. Обобщенные алгоритмы и итераторы
10.1. Улучшенные операции map(), filter() и reduce()
10.1.1. Операция map()
10.1.2. Операция filter()
10.1.3. Операция reduce()
10.1.4. Конвейер filter()/reduce()
10.1.5. Упражнения
10.2. Распространенные алгоритмы
10.2.1. Алгоритмы вместо циклов
10.2.2. Реализация текучего конвейера
10.2.3. Упражнения
10.3. Ограничение типов-параметров
10.3.1. Обобщенные структуры данных с ограничениями типа
10.3.2. Обобщенные алгоритмы с ограничениями типа
10.3.3. Упражнение
10.4. Эффективная реализация reverse и других алгоритмов с помощью итераторов
10.4.1. Стандартные блоки, из которых состоят итераторы
10.4.2. Удобный алгоритм find()
10.4.3. Эффективная реализация reverse()
10.4.4. Эффективное извлечение элементов
10.4.5. Краткое резюме по итераторам
10.4.6. Упражнения
10.5. Адаптивные алгоритмы
10.5.1. Упражнение
10.6. Резюме
10.7. Ответы на упражнения
Глава 11. Типы, относящиеся к более высокому роду, и не только
11.1. Еще более обобщенная версия алгоритма map
11.1.1. Обработка результатов и передача ошибок далее
11.1.2. Сочетаем и комбинируем функции
11.1.3. Функторы и типы, относящиеся к более высокому роду
11.1.4. Функторы для функций
11.1.5. Упражнение
11.2. Монады
11.2.1. Результат или ошибка
11.2.2. Различия между map() и bind()
11.2.3. Паттерн «Монада»
11.2.4. Монада продолжения
11.2.5. Монада списка
11.2.6. Прочие разновидности монад
11.2.7. Упражнение
11.3. Что изучать дальше
11.3.1. Функциональное программирование
11.3.2. Обобщенное программирование
11.3.3. Типы, относящиеся к более высокому роду, и теория категорий
11.3.4. Зависимые типы данных
11.3.5. Линейные типы данных
Резюме
11.4. Ответы на упражнения
Приложение А. Установка TypeScript и исходный код
Онлайн
На локальной машине
Исходный код
«Самодельные» реализации
Приложение Б.Шпаргалка по TypeScript