Обязательные этапы
Не допускайте вызова build(), пока не заданы все обязательные поля
«Обязательные этапы» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.
Запрет преждевременного build()
Теперь мы используем накопленное состояние, чтобы запретить вызов build(), пока обязательные поля не заданы. Неполную сборку блокирует система типов, а не проверка во время выполнения.
Определение итоговой структуры
Сначала объявите полный объект и укажите обязательные ключи. Сборщик разрешит build() только тогда, когда состояние будет содержать их все.
interface Config {
url: string; // required
method: string; // required
timeout?: number; // optional
}
type Required = { url: string; method: string };Условная сигнатура build
Мы делаем build доступным только тогда, когда накопленное состояние S расширяет набор обязательных ключей. Условный тип возвращает настоящий метод или непригодный для использования.
class Builder<S> {
build(this: Builder<Required>): Config {
return this.d as Config;
}
private d: Record<string, unknown> = {};
}Использование параметра this
Параметр this: Builder<Required> ограничивает, какие экземпляры сборщика могут вызвать build. Если S не соответствует Required, вызов приводит к ошибке типов.
// Only a Builder whose S includes url and method
// can legally invoke build().Связывание методов установки с состоянием
Каждый метод установки, как и прежде, расширяет S. После выполнения обоих обязательных методов S наконец расширяет Required, и build становится доступным.
class Builder<S> {
private d: Record<string, unknown> = {};
url(u: string): Builder<S & { url: string }> { this.d.url = u; return this as any; }
method(m: string): Builder<S & { method: string }> { this.d.method = m; return this as any; }
build(this: Builder<{ url: string; method: string }>): Config { return this.d as Config; }
}Успешный сценарий компилируется
Если оба обязательных шага присутствуют, цепочка проходит проверку типов и выполняется. Компилятор уверен, что S включает каждый обязательный ключ.
const cfg = new Builder<{}>().url("/x").method("GET").build();
console.log(cfg.url, cfg.method);Ошибочный сценарий не проходит проверку
Пропустите обязательный шаг — и build() больше не пройдёт проверку типов, потому что S сборщика не расширяет Required. Ошибка обнаруживается во время компиляции.
// const bad = new Builder<{}>().url("/x").build();
// Error: 'build' can only be called when method is set too.Почему это лучше проверок во время выполнения
Проверка во время выполнения if (!this.url) throw завершится ошибкой только при запуске кода. Подход с параметром this выявляет проблему во время проверки типов, поэтому неполные сборки никогда не попадут в выпуск.
Необязательные поля остаются необязательными
Необязательные шаги, например timeout, никогда не входят в Required, поэтому они не блокируют build(). Вы можете свободно добавлять их или пропускать.
const ok = new Builder<{}>().method("PUT").url("/y").build();
console.log("order of required steps does not matter");Масштабирование на множество требований
Добавьте больше обязательных ключей в структуру Required и параметр this — и компилятор будет проверять их все. Этот подход масштабируется на любое количество обязательных шагов.
Ограничения
Гарантия зависит от того, насколько последовательно S передаётся через каждый метод установки и используется типизация параметра this. Приведения типов следует ограничить методами установки, чтобы вызывающий код оставался полностью безопасным с точки зрения типов.
Быстрая проверка
Быстрая проверка по этому уроку.
Повторение
Чтобы обеспечить выполнение обязательных шагов, укажите для build параметр this: Builder<Required>. Метод проходит проверку типов только после того, как накопленное состояние S включает каждый обязательный ключ, превращая неполное создание объекта в ошибку компиляции.
Часто задаваемые вопросы
Урок «Обязательные этапы» бесплатный?
Да — полный текст урока «Обязательные этапы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.
Чему я научусь в уроке «Обязательные этапы»?
Не допускайте вызова build(), пока не заданы все обязательные поля Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать TypeScript Academy?
Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Обязательные этапы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке TypeScript Academy?
Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.