0Pricing
TypeScript Academy · Урок

Типы как язык вычислений

Рассматривайте систему типов как чистый функциональный язык

«Типы как язык вычислений» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.

Типы — это язык

В TypeScript бок о бок существуют два языка. Один — это JavaScript на уровне значений, который вы уже знаете. Другой — уровень типов, работающий полностью во время компиляции. В этом курсе вы учитесь программировать на втором языке.

Система типов — это небольшой чистый функциональный язык. Вы подаёте типы на вход, а он вычисляет типы на выходе. Ничего из этого не сохраняется во время выполнения.

type Greeting = "hello";
type Loud = Uppercase<Greeting>;
// Loud is "HELLO" - computed by the type system

Типы на входе, типы на выходе

Обобщённый тип по сути является функцией, преобразующей типы в типы. Параметр типа — это аргумент, а тело — возвращаемое значение.

Ниже Boxed принимает тип T и создаёт тип объекта, который его оборачивает. Представляйте T как параметр, который вы передаёте.

type Boxed<T> = { value: T };

type A = Boxed<number>; // { value: number }
type B = Boxed<string>; // { value: string }

Обобщённые типы — это функции

Сравните функцию на уровне значений с функцией на уровне типов. Их структура почти одинакова: параметры на входе, один результат на выходе.

  • Значение: const id = (x) => x
  • Тип: type Id<T> = T

Типовой Id просто возвращает всё, что ему передали.

type Id<T> = T;

type X = Id<boolean>; // boolean
type Y = Id<"abc">;  // "abc"

Нулевая стоимость во время выполнения

Всё, что относится к уровню типов, удаляется до запуска кода. В выходном JavaScript не остаётся никаких следов вычислений типов. Работающая программа не несёт никаких затрат производительности, независимо от сложности типов.

Поэтому программирование на уровне типов иногда называют бесплатным: оно влияет только на компилятор и никогда не попадает в сборку.

type Pair<T> = [T, T];
const p: Pair<number> = [1, 2];
// Compiled JS is just: const p = [1, 2];
console.log(p);

Несколько параметров

Функции на уровне типов могут принимать несколько параметров, как и обычные функции. Здесь Merge принимает два типа объектов и объединяет их.

Читайте это так: если заданы A и B, верните объект, содержащий все свойства обоих типов.

type Merge<A, B> = A & B;

type User = { id: number };
type Named = { name: string };
type NamedUser = Merge<User, Named>;
// { id: number; name: string }

Значения по умолчанию для параметров

Параметры типов могут иметь значения по умолчанию, как и аргументы функций по умолчанию. Если вызывающая сторона не указывает аргумент, используется значение по умолчанию.

type List<T = string> = T[];

type A = List;        // string[]
type B = List<number>; // number[]

Ограничения — это проверки

Ограничение с extends определяет, какие типы можно передавать. На уровне типов это эквивалентно проверке аргумента функции перед его использованием.

HasId принимает только типы, у которых уже есть свойство id, поэтому в теле его можно безопасно прочитать.

type GetId<T extends { id: number }> = T["id"];

type A = GetId<{ id: number; name: string }>; // number
// GetId<{ name: string }> would be a compile error

Вычисления, а не просто аннотации

Начинающие используют типы только для обозначения значений. При программировании на уровне типов типы используются для вычисления ответов. Например, встроенная вспомогательная конструкция ReturnType анализирует тип функции и извлекает тип её результата.

type Fn = (a: number) => string;
type R = ReturnType<Fn>; // string

type Fn2 = () => boolean;
type R2 = ReturnType<Fn2>; // boolean

Отображение свойств

Отображаемые типы позволяют преобразовать каждое свойство типа объекта. Это цикл в языке типов. Stringify превращает тип каждого значения в string.

type Stringify<T> = { [K in keyof T]: string };

type Input = { a: number; b: boolean };
type Out = Stringify<Input>; // { a: string; b: string }

Чистота и детерминированность

Язык типов является чистым: одинаковые входные данные всегда дают один и тот же выходной тип, без побочных эффектов. В нём нет мутаций, нет IO и нет времени. Именно эта чистота делает программы на уровне типов предсказуемыми и пригодными для композиции.

Благодаря чистоте рассуждать о типах можно так же, как о математике: с помощью подстановки.

type Square<T extends { area: number }> = T["area"];
// Always the same result for the same input shape

Зачем это нужно

Освоив этот второй язык, Вы сможете кодировать правила, которые компилятор будет бесплатно проверять: допустимые маршруты, исчерпывающие конструкции switch, безопасную обработку строк и интерфейсы, которыми невозможно воспользоваться неправильно. Весь остальной курс посвящён созданию набора таких инструментов.

Главная идея: тип — это значение в языке типов, а обобщённый тип — это функция.

type NonEmpty<T extends unknown[]> =
  T extends [unknown, ...unknown[]] ? T : never;
// Encodes a rule: the tuple must have at least one element

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете типы как язык вычислений.

Итоги

Вы узнали, что типы TypeScript образуют чистый функциональный язык, выполняющийся во время компиляции.

  • Обобщённые типы — это функции: типы на входе, типы на выходе.
  • Параметры поддерживают значения по умолчанию и ограничения extends.
  • Отображаемые типы перебирают свойства.
  • Всё стирается, поэтому затрат во время выполнения нет.

Далее Вы добавите этому языку условный оператор: условные типы.

Часто задаваемые вопросы

Урок «Типы как язык вычислений» бесплатный?

Да — полный текст урока «Типы как язык вычислений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.

Чему я научусь в уроке «Типы как язык вычислений»?

Рассматривайте систему типов как чистый функциональный язык Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать TypeScript Academy?

Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Типы как язык вычислений»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке TypeScript Academy?

Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Типы как язык вычислений
  2. Условные типы на уровне типов
  3. Рекурсия на уровне типов
  4. Распределяемые условные типы
← Назад к TypeScript Academy