any, unknown и never

Три специальных типа на краях системы: лазейка any, страховка unknown и тупик never.

any отключает проверку типов, unknown требует проверить значение перед использованием, never означает «значения не будет никогда».

any — лазейка, отключающая типы

Тип any говорит компилятору «не проверяй здесь ничего». С такой переменной можно делать что угодно — и потерять всю защиту:

let data: any = "строка";
data.foo.bar.baz;     // компилятор молчит
data();               // молчит
data * 10;            // молчит

Любая из этих строк рухнет в рантайме, но TypeScript не предупредит. По сути any возвращает нас в обычный нетипизированный JavaScript. Поэтому правило простое: избегайте any, особенно его неявного появления (для этого и нужен noImplicitAny из строгого режима).

unknown — безопасная альтернатива

Когда тип значения действительно заранее неизвестен (например, ответ внешнего API), берут unknown. В него можно записать что угодно, как в any, но использовать его, не проверив, нельзя:

let value: unknown = fetchData();

value.toUpperCase();
// Ошибка: 'value' is of type 'unknown'.

if (typeof value === "string") {
  value.toUpperCase(); // ок — внутри проверки тип сузился до string
}

Разница принципиальна: any снимает ответственность с программиста, unknown — заставляет проверить значение. Это превращает потенциальный рантайм-баг в обязательную проверку.

any против unknown

Свойствоanyunknown
Принимает любое значениедада
Можно использовать без проверкида (опасно)нет
Сохраняет безопасность типовнетда

never — то, чего не бывает

Тип never описывает значение, которого не может существовать. Он появляется у функций, которые никогда не возвращают управление — например, всегда бросают исключение или зацикливаются:

function fail(message: string): never {
  throw new Error(message);
}

Функция не возвращает значение в обычном смысле — она прерывает выполнение. Тип void здесь не подошёл бы: void значит «вернёт undefined», а never — «не вернёт вообще ничего».

Где never полезен на практике

never помогает гарантировать, что вы обработали все варианты. Если в switch по union-типу появится необработанный случай, присвоение в never вызовет ошибку компиляции — это «проверка на полноту»:

type Status = "ok" | "error";

function handle(s: Status): string {
  switch (s) {
    case "ok": return "Успех";
    case "error": return "Ошибка";
    default:
      const _exhaustive: never = s; // если добавят новый статус — здесь ошибка
      return _exhaustive;
  }
}

Итог

  • any отключает проверку типов — используйте как крайнюю меру.
  • unknown — безопасный «неизвестный тип»: требует проверки перед использованием.
  • never — значения не существует; помогает функциям без возврата и проверке полноты switch.
Проверьте себя
1. Чем unknown безопаснее, чем any?
Aunknown работает быстрее в рантайме
Bunknown требует проверить значение перед использованием, а any — нет
Cunknown принимает меньше значений
DМежду ними нет разницы
2. Какой тип возвращает функция, которая всегда бросает исключение?
Avoid
Bnever
Cany
Dundefined
3. Почему стоит избегать типа any?
AОн замедляет компиляцию
BОн отключает проверку типов и возвращает к небезопасному JavaScript
CОн не поддерживается в strict-режиме вообще
DОн работает только с числами
Поддержать проект