Тип never и невозможные состояния
Моделируйте недостижимый код и невозможные значения с помощью never
«Тип never и невозможные состояния» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.
Пустой тип
never — это пустой тип: он представляет значения, которые никогда не могут возникнуть. Ни одно значение нельзя присвоить never (кроме самого never). Он обозначает ситуации, которые должны быть невозможными.
// You cannot create a value of type never
function crash(): never {
throw new Error('boom');
}
try { crash(); } catch (e) { console.log('caught'); }Функции, которые никогда не возвращают результат
Функция, которая всегда выполняет throw, нормально не возвращается, поэтому её возвращаемый тип — never. Это сообщает вызывающему коду и компилятору, что выполнение останавливается здесь.
function fail(message: string): never {
throw new Error(message);
}
try { fail('invalid'); } catch (e) { console.log('handled'); }Бесконечные циклы возвращают пустой тип
Функция с бесконечным циклом также никогда не возвращается, поэтому ей тоже назначается тип never. Компилятор понимает, что выполнение не может продолжиться после неё.
function listen(): never {
while (true) {
// forever
break; // (break added so the demo terminates)
}
throw new Error('stopped');
}
console.log('listen has return type never');Пустой тип и отсутствие значения
Не путайте never с void. Функция типа void возвращается, просто выдавая результат без полезного значения. Функция типа never вообще не возвращает результат — она выбрасывает ошибку или выполняет бесконечный цикл.
function logIt(): void {
console.log('done'); // returns normally
}
function abort(): never {
throw new Error('stop'); // never returns
}
logIt();
try { abort(); } catch (e) { console.log('ok'); }Пустой тип при проверке полноты обработки
Самое практичное применение never — проверка полноты обработки. В ветви default конструкции switch присвойте переменную типу never. Если обработаны все варианты, переменная уже имеет тип never, и код компилируется.
type Shape = 'circle' | 'square';
function area(s: Shape): string {
switch (s) {
case 'circle': return 'pi r^2';
case 'square': return 'a^2';
default:
const _check: never = s; // ok: all handled
return _check;
}
}
console.log(area('square'));Обнаружение пропущенных вариантов
Если кто-то добавит новый элемент объединения, но забудет соответствующую ветвь, оставшееся значение больше не будет иметь тип never, поэтому присваивание не пройдёт компиляцию. Проверка с помощью never превращает незаметный пробел в явную ошибку.
type Shape = 'circle' | 'square' | 'triangle';
// If 'triangle' case is missing, assigning s to never
// would error: 'triangle' is not assignable to never.
console.log('Add a case for every member');Пустой тип в невозможных ветвях объединения
Когда сужение исключает все возможности, оставшийся тип становится never. Компилятор знает, что такая ветвь недостижима, и это может выявить ошибки в логике.
function check(x: string | number): void {
if (typeof x === 'string') {
console.log('string');
} else if (typeof x === 'number') {
console.log('number');
} else {
// x is never here
console.log('unreachable');
}
}
check('hi');Пустой тип как нижний тип
never — это нижний тип: его можно присвоить любому другому типу, поскольку несуществующее значение совместимо с чем угодно. Поэтому throw может находиться на месте любого выражения.
function getOrThrow(v: string | null): string {
return v ?? fail();
}
function fail(): never {
throw new Error('missing');
}
console.log(getOrThrow('value'));Фильтрация объединений до пустого типа
В условных и отображаемых типах never действует как команда «удалить это». Объединение с never ничего не меняет: T | never — это просто T. Поэтому этот тип естественно использовать для фильтрации.
type Keep<T> = T extends string ? T : never;
type R = Keep<'a' | 1 | 'b'>; // 'a' | 'b'
const x: R = 'a';
console.log(x);Моделирование невозможных состояний
Используйте never в формах объектов, чтобы сделать недопустимые сочетания непредставимыми. Здесь состояние «загрузка» не может одновременно содержать данные, потому что тип это запрещает.
type State =
| { status: 'loading'; data?: never }
| { status: 'ready'; data: number };
const s: State = { status: 'ready', data: 7 };
console.log(s);Пустой тип повышает безопасность рефакторинга
Поскольку проверки полноты с помощью never завершаются ошибкой при пропущенном варианте, они делают рефакторинг безопаснее: расширьте объединение — и компилятор укажет каждое место, которое нужно обновить.
type Cmd = 'start' | 'stop';
function run(c: Cmd): string {
if (c === 'start') return 'starting';
if (c === 'stop') return 'stopping';
const _x: never = c;
return _x;
}
console.log(run('start'));Быстрая проверка
Проверьте, насколько хорошо Вы поняли пустой тип.
Повторение: пустой тип
Вы узнали, что never:
- Является пустым типом — ни одно значение не может иметь тип never.
- Является возвращаемым типом функций, которые выбрасывают ошибку или выполняются бесконечно.
- Обеспечивает проверку полноты вариантов в ветвях switch по умолчанию.
- Появляется в ветвях с невозможным сужением типа и фильтрует объединения типов в логике типов.
Далее мы рассмотрим тип void и его отличия.
function assertNever(x: never): never {
throw new Error('Unexpected: ' + String(x));
}
console.log('assertNever guards exhaustiveness');Часто задаваемые вопросы
Урок «Тип never и невозможные состояния» бесплатный?
Да — полный текст урока «Тип never и невозможные состояния» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.
Чему я научусь в уроке «Тип never и невозможные состояния»?
Моделируйте недостижимый код и невозможные значения с помощью never Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать TypeScript Academy?
Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Тип never и невозможные состояния»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке TypeScript Academy?
Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Понимание unknown и any
- Тип never и невозможные состояния
- Тип void в функциях
- Типобезопасная работа с unknown