Тип never — это один из специальных типов TypeScript, который указывает на значения, которые никогда не могут появиться. Обычно он используется в двух случаях: когда функция всегда выбрасывает ошибку (и не возвращает управление) или когда в ней находится бесконечный цикл.
Также never незаменим при сужении типов (Type Narrowing) для проверки исчерпываемости (exhaustiveness checking) в конструкциях switch. Если вы обработали все возможные варианты union-типа, оставшийся тип будет never. Этот урок и практические задания научат вас отличать never от void и использовать его для создания надежного кода, который защищен от логических дыр.
- Модуль 1: Введение в TypeScript
- Модуль 2: Примитивные типы
- Модуль 3: Специальные типы
- Модуль 4: Массивы
- Модуль 5: Кортежи (Tuples)
- Модуль 6: Объекты
- Модуль 7: Функции
- Модуль 8: Union типы
- Модуль 9: Литеральные типы
- Модуль 10: Type Aliases
- Модуль 11: Интерфейсы
- Модуль 12: Type Guards и Narrowing
- Модуль 13: Enums
- Модуль 14: Классы
- Модуль 15: Generics — основы
- Модуль 16: Generics — ограничения
- Модуль 17: Utility Types — базовые
- Модуль 18: Utility Types — работа с Union
- Модуль 19: Utility Types — функции
- Модуль 20: Type Assertions
- Модуль 21: Keyof и Typeof операторы
- Модуль 22: Mapped Types
- Модуль 23: Conditional Types
- Модуль 24: Discriminated Unions
- Модуль 25: Модули и типы
- Модуль 26: Declaration Files
- Модуль 27: Типизация асинхронного кода
- Модуль 28: Практические паттерны
1. Void vs Never
Сопоставьте описание поведения функции в TypeScript с её возвращаемым типом (void или never). В левой колонке приведены описания поведения функций, а в правой — возможные возвращаемые типы. Обратите внимание, что тип never используется для функций, которые никогда не завершаются (например, выбрасывают исключение или содержат бесконечный цикл), а void — для функций, которые завершаются нормально, не возвращая значения.
voidvoidnevernevernever2. Функции never
Внимательно изучите приведённый ниже код на TypeScript, содержащий несколько объявлений функций. Ваша задача — кликнуть и выделить только те функции, которые должны иметь возвращаемый тип `never` (то есть функции, которые никогда не завершаются нормально: либо выбрасывают ошибку, либо содержат бесконечный цикл). Не отмечайте функции, которые возвращают какое-либо значение или тип, отличный от `never`.
function {{processData~|~t1}}(input: string): void {
console.log(input);
}
function {{throwError~|~t2}}(msg: string): never {
throw new Error(msg);
}
function {{infiniteLoop~|~t3}}(): never {
while (true) {
// Бесконечный цикл
}
}
function {{calculateSum~|~t4}}(a: number, b: number): number {
return a + b;
}
function {{logMessage~|~t5}}(msg: string): void {
console.log(msg);
}
function {{alwaysThrow~|~t6}}(): never {
throw new TypeError('Invalid operation');
}3. Аннотация возвращаемого типа
В этом задании вам нужно дополнить код функции-обработчика ошибок, выбрав правильный тип возвращаемого значения из предложенных вариантов. Функция выбрасывает исключение и никогда не завершается нормально — подумайте, какой тип TypeScript лучше всего описывает такое поведение. Выберите подходящий вариант из выпадающего списка для каждого пропуска в коде.
function handleError(errorMessage: string): input1S {
throw new Error(errorMessage);
}4. Исчерпывающая проверка
В этом задании вам нужно дополнить код, который использует конструкцию switch для обработки различных типов данных. В блоке default переменная должна быть присвоена типу never для обеспечения исчерпывающей проверки. Впишите ключевое слово never в аннотацию переменной проверки, чтобы код компилировался и выполнялся корректно. Обратите внимание, что тип never используется для указания, что функция никогда не возвращает значение или что переменная не может иметь никакого значения.
function processValue(value: string | number | boolean): string {
switch (typeof value) {
case 'string':
return `Строка: ${value}`;
case 'number':
return `Число: ${value}`;
case 'boolean':
return `Булево: ${value}`;
default:
const exhaustiveCheck: input1S = value;
throw new Error(`Неизвестный тип: ${exhaustiveCheck}`);
}
}
console.log(processValue('Привет'));
console.log(processValue(42));
console.log(processValue(true));5. Ложная аннотация
В этом фрагменте кода TypeScript функция помечена как возвращающая тип `never`, но внутри неё есть оператор `return true`. Это противоречит определению типа `never`, который указывает, что функция никогда не возвращает управление (например, всегда выбрасывает исключение или зацикливается). Найдите и исправьте строку с ошибкой, чтобы функция соответствовала своей аннотации типа.
function throwError(): never { return true;}6. Логика сужения типов
Перед вами строки TypeScript-кода, демонстрирующие использование типа never в конструкции switch для сужения типов. Строки перемешаны. Расставьте их в правильном порядке, чтобы получилась корректная функция, которая обрабатывает все возможные значения объединённого типа и завершается присваиванием к never в ветке default, если обнаруживается лишний тип. Это упражнение иллюстрирует логику сужения типов и гарантирует полноту обработки всех вариантов.
break; default:} case 'circle': case 'square': break; console.log('Processing square'); break; console.log('Processing triangle');function processShape(shape: Shape): void { switch (shape) { throw new Error(`Unexpected shape: ${exhaustiveCheck}`); const exhaustiveCheck: never = shape; }type Shape = 'circle' | 'square' | 'triangle'; console.log('Processing circle'); case 'triangle':7. Поведение кода
Проанализируйте приведённый код на TypeScript. Внимательно изучите функцию, возвращающую тип never, и её вызов. Что произойдёт при попытке выполнения этого кода? Выберите единственный правильный вариант поведения программы.
function throwError(message: string): never {
throw new Error(message);
}
function processValue(value: number): string {
if (value > 0) {
return "Positive";
} else if (value < 0) {
return "Negative";
} else {
throwError("Value cannot be zero");
}
}
console.log("Start");
const result = processValue(0);
console.log("Result:", result);
console.log("End");