← Назад к вопросам

Расскажи про отличия void,never, unknown, any

2.0 Middle🔥 141 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Отличия void, never, unknown, any в TypeScript

В TypeScript типы void, never, unknown и any представляют собой специальные типовые аннотации, играющие различные, но критически важные роли в системе типов. Их понимание — ключ к написанию типобезопасного и выразительного кода.

void — Отсутствие возвращаемого значения

Тип void указывает на то, что функция не возвращает никакого значения или возвращает undefined/null (в зависимости от настроек strictNullChecks). Это наиболее часто используется для аннотирования возвращаемого типа функций, которые выполняют побочные эффекты, но не возвращают данные вызывающему коду.

// Функция с типом возврата void
function logMessage(message: string): void {
  console.log(message);
  // Явного return нет, возвращается undefined
}

// Переменная типа void может содержать только undefined или null (если разрешено)
let unusable: void = undefined;

Где используется:

  • Аннотация возвращаемого типа для функций-обработчиков событий, lifecycle-методов.
  • Тип для значений, когда нас интересует только побочный эффект операции.

never — Тип для значений, которых не существует

Тип never представляет собой тип значений, которые никогда не возникают. Это сигнал о том, что функция никогда не завершится нормально, а код в этой точке исполняться не будет.

// Функция, которая всегда выбрасывает ошибку
function throwError(message: string): never {
  throw new Error(message);
  // Код после throw никогда не выполнится.
}

// Функция с бесконечным циклом
function infiniteLoop(): never {
  while (true) {
    // ...
  }
  // Сюда управление не вернется.
}

// never появляется в exhaustive checks
type Shape = | { kind: "circle"; radius: number }
             | { kind: "square"; side: number };

function getArea(shape: Shape): number {
    switch (shape.kind) {
        case "circle": return Math.PI * shape.radius ** 2;
        case "square": return shape.side ** 2;
        default:
            // В этой точке тип shape — never,
            // потому что все варианты обработаны.
            const _exhaustiveCheck: never = shape;
            return _exhaustiveCheck;
    }
}

Ключевые свойства never:

  • Является подтипом любого типа (never можно присвоить куда угодно).
  • Над ним нет никакого типа (кроме never). Ему нельзя ничего присвоить.
  • Используется компилятором для контроля полноты проверок в условных конструкциях (exhaustiveness checking).

unknown — Type-safe аналог any

Тип unknown — это типобезопасная вершина иерархии типов TypeScript. Он говорит: «я знаю, что здесь какое-то значение, но я не знаю его типа». Чтобы выполнить над ним какую-либо операцию, его необходимо сначала сузить до конкретного типа (с помощью typeof, instanceof, type assertion или пользовательской проверки типов).

let userInput: unknown;
let userName: string;

userInput = 5;
userInput = "Max";

// Ошибка! unknown нельзя напрямую присвоить string
// userName = userInput;

// Корректно: Сужение типа с помощью проверки
if (typeof userInput === "string") {
  userName = userInput; // Теперь TypeScript знает, что здесь string
}

// Корректно: Сужение типа через утверждение (type assertion)
userName = userInput as string;

Преимущество перед any: unknown заставляет разработчика явно проверять тип перед использованием, предотвращая случайные ошибки во время выполнения.

any — Отключение проверки типов

Тип any — это мощный, но опасный тип, который полностью отключает проверку типов для значения. Переменной типа any можно присвоить что угодно, и с ней можно делать что угодно. TypeScript доверяет разработчику на все 100%.

let flexibleValue: any;

// Все эти операции разрешены без ошибок компиляции
flexibleValue = 42;
flexibleValue = "Hello World";
flexibleValue = { name: "John" };
flexibleValue.toUpperCase(); // Компилятор не ругается, но это вызовет ошибку в runtime!
flexibleValue.nonExistentMethod(); // И это тоже.

Когда (очень осторожно) использовать:

  • При постепенной миграции JavaScript-кода на TypeScript.
  • При работе со сложными динамическими структурами, типизировать которые непрактично (например, данные от сторонних API без четкого контракта). Но unknown почти всегда предпочтительнее.

Сводная таблица сравнения

Критерийvoidneverunknownany
НазначениеОтсутствие значимого возвращаемого значения.Значение, которое никогда не возникает.Значение неизвестного типа (требует проверки).Значение любого типа (проверка отключена).
Безопасность типовВысокая.Высокая.Высокая (требует сужения).Нулевая.
ПрисваиваемостьМожет быть присвоен undefined/null.Нельзя присвоить ничему (кроме never).Нельзя присвоить другому типу без сужения/утверждения.Можно присвоить куда угодно.
Что можно присвоитьТолько undefined, null (или void).Ничего, кроме never.Можно присвоить что угодно.Можно присвоить что угодно.
ОперацииПочти никакие (кроме присвоения).Никакие (код недостижим).Запрещены до сужения типа.Разрешены любые (ответственность на разработчике).
ИспользованиеВозвращаемый тип функций без return.Для функций, генерирующих ошибки, бесконечных циклов, exhaustive checks.Для типобезопасной работы с динамическими данными.Для отключения проверки типов (крайняя мера).

Практический совет: Стремитесь к использованию unknown вместо any везде, где это возможно. Это превращает потенциальные ошибки рантайма в ошибки компиляции, которые можно обнаружить и исправить на этапе разработки. never — ваш союзник для моделирования невозможных состояний и контроля за полнотой логики. void — стандартный инструмент для описания функций-процедур. any следует использовать осознанно, четко понимая, что вы временно жертвуете главным преимуществом TypeScript — статической типобезопасностью.