Типы: null, undefined, void, never
null,undefined,voidиnever— четыре специальных типа TypeScript для отсутствующих, несуществующих или невозможных значений, каждый со своей семантикой и правилами использования.
Зачем нужно
Эти типы описывают «отсутствие значения» по-разному: null — намеренное отсутствие, undefined — неинициализированное, void — функция ничего не возвращает, never — код никогда не достигается. Понимание различий критично при strictNullChecks.
Где используется
null— намеренное «нет значения» в полях объектов и возвратах функцийundefined— неинициализированные переменные, отсутствующие опциональные поляvoid— возвращаемый тип функций без return-значения и callback-овnever— exhaustive check, функции-исключения, фильтрация union
Основной контент
null — намеренное отсутствие
// С strictNullChecks: true
function findUser(id: string): User | null {
return users.find(u => u.id === id) ?? null;
}
const user = findUser("u-1");
// user.name; // Error: Object is possibly 'null'
if (user !== null) {
console.log(user.name); // OK
}
// Optional chaining
const name = findUser("u-1")?.name ?? "Guest";
undefined — неинициализированное
let x: string;
// console.log(x); // Error: Variable 'x' is used before assignment
// Опциональные свойства — undefined
interface Config {
host: string;
port?: number; // number | undefined
}
function getPort(config: Config): number {
return config.port ?? 3000; // если undefined — дефолт
}
// Разница null vs undefined:
const obj = { a: null, b: undefined };
"a" in obj; // true
"b" in obj; // true
obj.a === null; // true
obj.b === undefined; // true
void — нет возвращаемого значения
// Функция с void return type
function log(message: string): void {
console.log(message);
// return; // OK
// return undefined; // OK
// return "value"; // Error
}
// void в callback — важный нюанс
type Callback = () => void;
const cb: Callback = () => {
return 42; // OK! void означает «возвращаемое значение игнорируется»
};
const result = cb; // result: void (нельзя использовать как number)
// forEach ожидает => void — push возвращает number, но это OK
[1, 2, 3].forEach((n) => .push(n));
never — недостижимый код
// 1. Функции которые никогда не завершаются нормально
function throwError(message: string): never {
throw new Error(message);
}
function infiniteLoop: never {
while (true) {}
}
// 2. Exhaustive check
type Shape = { kind: "circle" } | { kind: "square" };
function describe(shape: Shape): string {
switch (shape.kind) {
case "circle": return "Круг";
case "square": return "Квадрат";
default:
const _never: never = shape; // Error если добавить вариант без case
return _never;
}
}
// 3. Невозможные пересечения
type Impossible = string & number; // never
// 4. never в union «исчезает»
type A = string | never; // string
type B = number | never; // number
Сравнительная таблица
null |
undefined |
void |
never |
|
|---|---|---|---|---|
| Присваивается | null |
undefined |
undefined |
ничто |
| Использование | отсутствие | неинициализировано | нет return | недостижимо |
Assignable к any |
Да | Да | Да | Да |
Assignable к unknown |
Да | Да | Да | Да |
Частые ошибки
- Путать
undefinedи опциональный (?) —x?: stringэтоstring | undefined;x: undefined— всегда undefined. - Думать что
void === undefined— в callback void разрешает вернуть любое значение; как тип переменнойvoid≠undefined. - Не проверять
nullприstrictNullChecks— без проверки нельзя использовать nullable тип. - Не добавлять exhaustive check с
never— безassertNeverдобавление варианта в union не вызовет ошибку компиляции.
Связанные темы
- any unknown never void
- any, unknown -- различия
- Типизация функций -- параметры и возврат
- Discriminated Unions
- _MOC TypeScript