0Pricing
TypeScript Academy · Урок

Тип 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 — локальная установка не требуется.

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

  1. Понимание unknown и any
  2. Тип never и невозможные состояния
  3. Тип void в функциях
  4. Типобезопасная работа с unknown
← Назад к TypeScript Academy