Утверждения и проверки типов
По возможности отдавайте предпочтение проверкам во время выполнения, а не утверждениям
«Утверждения и проверки типов» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.
Два способа убедить компилятор
Когда компилятор не знает точный тип значения, у вас есть два варианта: утвердить его тип или проверить его во время выполнения. Выглядят они похоже, но обеспечивают совершенно разный уровень безопасности.
function viaAssert(v: unknown): number {
return (v as number) + 1; // claim
}
function viaGuard(v: unknown): number {
return typeof v === 'number' ? v + 1 : 0; // prove
}
console.log(viaAssert(5), viaGuard(5), viaGuard('x'));Утверждения не проверяют
Утверждение — это обещание без принудительной проверки. Если вы ошиблись, ошибка проявится только во время выполнения. Утверждения обменивают безопасность на удобство.
const v: unknown = 'hello';
const n = v as number;
console.log(n.toFixed(2)); // runtime error: toFixed is not a functionПроверки типа подтверждают тип во время выполнения
Проверка типа действительно проверяет значение. Если проверка пройдена, и вы, и компилятор знаете, что тип правильный: сужение подтверждено настоящей проверкой во время выполнения.
function toFixed2(v: unknown): string {
if (typeof v === 'number') return v.toFixed(2);
return 'N/A';
}
console.log(toFixed2(3.14159), toFixed2('hi'));Пользовательские функции проверки типа
Заключите сложные проверки в повторно используемую функцию, возвращающую value is T. Весь проект выиграет от одной хорошо проверенной функции валидации.
type Email = { address: string };
function isEmail(v: unknown): v is Email {
return typeof v === 'object' && v !== null &&
'address' in v && typeof (v as any).address === 'string';
}
console.log(isEmail({ address: 'a@b.com' }), isEmail(null));Проверки типа можно комбинировать и повторно использовать
Поскольку проверки типа — обычные функции, их можно объединять, проверять и повторно использовать. Утверждения же представляют собой разбросанные по коду заявления, которые нельзя централизованно проверить.
function isString(v: unknown): v is string { return typeof v === 'string'; }
function isNonEmpty(v: unknown): v is string {
return isString(v) && v.length > 0;
}
console.log(isNonEmpty('hi'), isNonEmpty(''));Функции утверждения с ключевым словом утверждения
TypeScript также предлагает функции утверждения. В их аннотации возвращаемого значения используется ключевое слово asserts. Если функция завершается обычным образом, компилятор сужает тип аргумента начиная с этого места; если условие не выполняется, функция выбрасывает исключение.
function assertNumber(v: unknown): asserts v is number {
if (typeof v !== 'number') throw new Error('not a number');
}
function use(v: unknown): number {
assertNumber(v); // after this line, v is number
return v * 2;
}
console.log(use(21));Утверждения и проверки типа
Проверка value is T возвращает логическое значение, по которому вы выбираете ветвь. Функция asserts value is T выбрасывает исключение при неудаче и сужает тип на оставшейся части области видимости. Оба подхода опираются на выполнение программы, в отличие от обычного as.
function assertDefined<T>(v: T): asserts v is NonNullable<T> {
if (v === null || v === undefined) throw new Error('missing');
}
const maybe: string | null = 'ok';
assertDefined(maybe);
console.log(maybe.length); // narrowed to stringУниверсальные помощники для утверждений
Функции утверждения отлично подходят для повторно используемых предварительных условий. Одна вспомогательная функция assert(condition) может проверять инварианты по всему коду и сразу останавливать выполнение при нарушениях.
function assert(cond: unknown, msg: string): asserts cond {
if (!cond) throw new Error(msg);
}
function half(n: number): number {
assert(n % 2 === 0, 'must be even');
return n / 2;
}
console.log(half(8));Сравнение безопасности
От наиболее безопасных к наиболее рискованным: проверки типа и функции утверждения (с проверкой во время выполнения) стоят выше обычных утверждений as (без проверки), а те — выше двойных утверждений (активно вводящих в заблуждение). Выбирайте самый безопасный подход, подходящий для вашей задачи.
// Safe: guard
function safe(v: unknown) {
return typeof v === 'string' ? v.trim() : '';
}
console.log(safe(' hi '));Выбор подходящего инструмента
Используйте проверку типа, когда выбираете ветвь по типу. Используйте функцию утверждения, когда предварительное условие должно выполняться или выполнение нужно остановить. Используйте as только тогда, когда сужение невозможно (например, для специализации DOM).
function getInput(v: unknown): asserts v is string {
if (typeof v !== 'string') throw new Error('expected string');
}
const raw: unknown = 'name';
getInput(raw);
console.log(raw.toUpperCase());Проверки во время выполнения надёжнее
Главная мысль этого курса: предпочитайте проверки во время выполнения утверждениям. Проверки типа и функции утверждения дают и типы на этапе компиляции, и безопасность во время выполнения. Утверждения дают только заявление.
function parsePort(v: unknown): number {
if (typeof v === 'number' && Number.isInteger(v)) return v;
throw new Error('invalid port');
}
console.log(parsePort(8080));Быстрая проверка
Проверьте, насколько хорошо вы понимаете разницу между утверждениями и проверками типа.
Повторение: утверждения и проверки типа
Вы узнали, что:
- Проверки типа (
value is T) подтверждают тип во время выполнения и позволяют выбирать ветвь. - Функции утверждения (
asserts value is T) выбрасывают исключение при неудаче и сужают тип после этого. - Обычные утверждения
asтолько заявляют тип и не обеспечивают безопасности во время выполнения. - Предпочитайте инструменты с проверкой во время выполнения; оставляйте утверждения для случаев, с которыми сужение не справляется.
Следующий курс: опциональная цепочка и оператор нулевого слияния.
function isPositive(v: unknown): v is number {
return typeof v === 'number' && v > 0;
}
console.log(isPositive(5), isPositive(-1));Часто задаваемые вопросы
Урок «Утверждения и проверки типов» бесплатный?
Да — полный текст урока «Утверждения и проверки типов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.
Чему я научусь в уроке «Утверждения и проверки типов»?
По возможности отдавайте предпочтение проверкам во время выполнения, а не утверждениям Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать TypeScript Academy?
Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Утверждения и проверки типов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке TypeScript Academy?
Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Ключевое слово as для утверждений типов
- Оператор утверждения ненулевого значения
- Двойные утверждения и их риски
- Утверждения и проверки типов