- Главная
- Typescript
- TypeScript: повторение ключевых тем курса
TypeScript: повторение ключевых тем курса
Содержание
- Аннотации типов и строгая типизация
- Массивы, объекты и union-тип
- Сужение типов, guards и алиасы
- Путь от JavaScript к TypeScript
- TSX и TSC два инструмента компиляции
- Настройка проекта через tsconfig.json
- Интерфейсы и переиспользование типов
- Промисы и generics
- Утилитные типы Partial Pick и Omit
- Когда строгая типизация мешает
- Итоги
За двадцать уроков мы прошли путь от первых аннотаций типов до generics и тонкой настройки компилятора. В этом уроке нет новой теории — вместо этого мы соберём всё пройденное в единую картину, чтобы перед практикой с реальным проектом ничего не потерялось. Такой обзор особенно полезен, если какие-то темы шли плотно друг за другом и детали могли стереться из памяти.
- Синтаксис TypeScript: аннотации, массивы, объекты и unions
- Инструменты:
TSX,TSCи настройкаtsconfig.json - Продвинутые типы: интерфейсы, generics и утилитные типы
- Работа с ошибками компилятора и типом
any
Аннотации типов и строгая типизация
Всё началось с аннотаций типов — способа явно указать TypeScript, какого типа переменная, параметр функции или возвращаемое значение. В отличие от JavaScript, где тип значения определяется только во время выполнения, TypeScript проверяет соответствие типов ещё на этапе написания кода. Мы разбирали примитивные типы вроде string, number и boolean, а также литеральные типы, которые сужают допустимые значения до конкретного набора.
function add(a: number, b: number): number {
return a + b;
}
let username: string = "Anjana";
Массивы, объекты и union-тип
Дальше мы научились типизировать более сложные структуры данных. Тип массива задаётся с помощью квадратных скобок после базового типа, а тип объекта описывается фигурными скобками с перечислением свойств и их типов. Отдельное внимание уделили необязательным свойствам объекта, которые помечаются знаком вопроса и допускают значение undefined.
Следом появились union-типы — способ объединить несколько типов в один с помощью символа |. Они пригодились там, где значение может быть, например, либо строкой, либо числом, а TypeScript должен принимать оба варианта как допустимые.
interface User {
id: number;
name: string;
email?: string;
}
const tags: string[] = ["typescript", "types"];
let id: string | number;
Сужение типов, guards и алиасы
Union-тип полезен, но перед обращением к специфичным свойствам значения TypeScript требует его сузить — иначе компилятор не даст, например, вызвать метод строки на значении, которое может оказаться числом. Для этого мы использовали проверки вроде typeof и in, а также писали собственные type guards для более сложных случаев. Тип-алиасы, объявляемые через type, позволили давать длинным описаниям типов короткие имена и переиспользовать их в разных частях проекта.
Путь от JavaScript к TypeScript
Отдельный блок уроков был посвящён практической миграции. Мы переименовывали файлы с расширения .js на .ts и использовали утилиту TSX, чтобы запускать TypeScript-файлы напрямую, без предварительной компиляции. На практике мы добавляли аннотации к переменным и функциям, обрабатывали возможные undefined-значения и опирались на встроенный вывод типов там, где TypeScript мог определить тип сам.
Не переименовывайте сразу все файлы проекта в .ts. Начните с одного модуля, запустите проверку через tsc --noEmit, исправьте появившиеся ошибки и только потом переходите к следующему файлу — так миграция останется управляемой и предсказуемой.
TSX и TSC два инструмента компиляции
Мы подробно разобрали разницу между двумя утилитами. TSX нужен для быстрого запуска и итерации по коду без строгой проверки типов, а TSC — это полноценный компилятор TypeScript, который проверяет типы и превращает TypeScript-код в обычный JavaScript.
| Инструмент | Назначение |
|---|---|
| TSX | Быстрый запуск .ts-файлов без строгой проверки типов |
| TSC | Проверка типов и компиляция TypeScript в JavaScript |
Мы также разобрали, что вся дополнительная синтаксическая информация TypeScript существует только на этапе компиляции и полностью исчезает в итоговом JavaScript-файле. Флаги вроде --noEmit, --checkJs и --strict позволяют управлять тем, что именно компилятор проверяет и какие файлы создаёт на выходе.
Настройка проекта через tsconfig.json
Чтобы не указывать одни и те же флаги вручную при каждом запуске, мы перенесли настройки компилятора в файл tsconfig.json. Там же мы задавали целевую версию JavaScript с помощью опции target, ведь разные версии среды выполнения поддерживают разный синтаксис. Отдельно рассмотрели базовые конфигурации — готовые наборы настроек для конкретных сред вроде Node.js или React, которые можно подключить и расширить вместо ручной настройки с нуля.
Интерфейсы и переиспользование типов
Интерфейсы стали основным способом описывать форму объектов в проекте. В отличие от простых объектных типов, интерфейсы можно расширять с помощью extends, наращивая более специфичные типы поверх общих. Это особенно удобно, когда несколько сущностей в приложении имеют общий набор базовых свойств.
interface Entity {
id: number;
}
interface Event extends Entity {
title: string;
host: string;
}
Промисы и generics
С асинхронным кодом мы научились явно указывать, значение какого типа вернёт промис, используя угловые скобки после Promise. А чтобы не дублировать похожие типы для разных случаев, мы освоили generics — типы, принимающие параметр типа в угловых скобках и подставляющие его позже, в момент использования.
async function loadUser(id: number): Promise<User> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
function identity<T>(value: T): T {
return value;
}
Утилитные типы Partial Pick и Omit
На основе одного базового типа TypeScript позволяет строить производные с помощью встроенных утилитных типов. Partial делает все свойства типа необязательными, а Pick и Omit помогают собрать более узкий тип, выбрав или, наоборот, исключив конкретные свойства.
type UserPreview = Pick<User, "id" | "name">;
type UserWithoutEmail = Omit<User, "email">;
type PartialUser = Partial<User>;
Partialделает все свойства типа необязательнымиPickвыбирает нужные свойства из типаOmitисключает указанные свойства из типа
Когда строгая типизация мешает
Иногда TypeScript не может корректно вывести тип, а переписывать логику ради компилятора нет времени. Для таких редких случаев существует тип any, отключающий проверку типов для конкретного значения, и комментарий // @ts-ignore, который заставляет компилятор пропустить ошибку на следующей строке. Оба инструмента стоит использовать точечно и осознанно, а не как способ обойти типизацию по умолчанию.
Если пришлось поставить // @ts-ignore, обязательно оставляйте рядом комментарий с причиной и задачей на исправление — иначе через месяц никто не вспомнит, почему проверка типов была отключена именно в этом месте.
Итоги
Мы прошли путь от простых аннотаций типов до интерфейсов, generics и утилитных типов, а заодно разобрались с инструментами TSX и TSC и настройкой проекта через tsconfig.json. Эта база пригодится в следующей части курса, где мы начнём применять TypeScript на реальном проекте Event Me.
В следующем уроке разберём, как встроить проверку типов в повседневный процесс разработки — с помощью флага --noEmit и режима --watch.