> В чем разница между типами void и never в TypeScript (TypeScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: ООО Премиум ИТ Солюшен, IT-One, Altenar
Стек: TypeScript
> Пример ответа
Короткий ответ
void обозначает отсутствие возвращаемого значения у функции - она завершается без return или с return undefined. never - это тип значения, которого никогда не существует: функция, которая всегда выбрасывает исключение или уходит в бесконечный цикл, либо переменная после сужения типа, которая не может иметь ни одного допустимого значения. void возвращает undefined, never не возвращает ничего.
Подробное объяснение
void - это тип, который присваивается функциям, не возвращающим явно значение. В JavaScript такая функция возвращает undefined, поэтому void совместим с undefined. Используется для callback’ов, обработчиков событий, middleware.
never - это нижний тип (bottom type), который является подтипом любого типа, но сам не имеет значений. Функция с типом возврата never никогда не завершится нормально. Также never появляется при исчерпывающих проверках (exhaustive checks) в discriminated unions - когда все варианты обработаны, остаётся never.
Ключевое различие: void - это отсутствие значения, которое всё же может быть представлено как undefined. never - это невозможность значения, его нельзя присвоить ничему, кроме самого never.
На практике
voidиспользуют для функций с побочными эффектами (логирование, запись в store, emit события).neverприменяют для функций, которые всегда падают с ошибкой (например,throw new Error()), или для бесконечных циклов (polling, server listener).neverполезен в type narrowing: послеif/switch, когда все варианты разобраны, TypeScript присваивает остаткуnever, что позволяет компилятору проверить полноту покрытия.- В generic-коде
neverможет исключать определённые типы из union (через conditional types).
Пример кода
TYPESCRIPT// void - функция возвращает undefinedfunction logMessage(msg: string): void {console.log(msg);// return undefined; // неявно}// never - функция никогда не завершаетсяfunction throwError(message: string): never {throw new Error(message);}function infiniteLoop(): never {while (true) {}}// never в discriminated uniontype 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 _exhaustive: never = shape;return _exhaustive;}}
Как отвечать на собеседовании
Начни с чёткого определения: void - отсутствие возврата, never - невозможность возврата. Приведи примеры функций для каждого типа. Объясни, что void совместим с undefined, а never - нет. Упомяни use case с discriminated union и exhaustive check - это показывает понимание продвинутой типизации. Если спросят про присваивание: void можно присвоить undefined, never нельзя присвоить ничего, но сам never можно присвоить любому типу (как bottom type).
Что проверяет интервьюер
- Понимание системы типов TypeScript на уровне junior/senior: различие между "нет значения" и "невозможное значение".
- Знание практических сценариев: обработка ошибок, бесконечные циклы, type narrowing.
- Умение использовать
neverдля исчерпывающих проверок - признак опыта работы с discriminated unions. - Понимание, что
void- это не то же самое, чтоundefined, хотя они совместимы.
Типичные ошибки
- Путать
voidсnever: говорить, чтоvoid- это "функция ничего не возвращает", аnever- "функция возвращает ошибку" (на самом делеneverне возвращает ничего, даже ошибки). - Думать, что
neverможно присвоитьundefinedили наоборот. - Использовать
voidдля функций, которые всегда бросают исключение - это семантически неверно, хотя TypeScript не выдаст ошибки. - Не использовать
neverв exhaustive check, оставляяdefaultбез проверки типа - это снижает безопасность кода.
> Похожие задачи по frontend
Что происходит при объединении полей с конкретными значениями в TypeScript?
Что такое дженерики в TypeScript и для чего они используются
В чем отличие Type и Enum в TypeScript и как они выглядят после компиляции
Можно ли создать два интерфейса или типа с одинаковым именем, но разным описанием в TypeScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью