Avatar ·

Как в TypeScript одновременно проверить переменную на null и undefined?

Всем привет! Я новичок в TypeScript и никак не могу разобраться с проверками на null и undefined. У меня есть функция, которая получает данные от пользователя (например, из формы или localStorage). Данные могут быть как null, так и undefined. Я хочу написать универсальную проверку, которая отловит оба случая. Вот мой код: ```typescript function processValue(value: string | null | undefined) { // Как правильно проверить, что value не null и не undefined? if (value !== null && value !== undefined) { console.log(value.toUpperCase()); } else { console.log('Значение отсутствует'); } } ``` Я знаю, что можно написать `value !== null && value !== undefined`, но это выглядит громоздко. Есть ли более короткий и элегантный способ? Я слышал про оператор `??`, но он вроде работает по-другому — он возвращает значение по умолчанию, а не проверяет. Также меня интересует: что будет, если я просто напишу `if (value)`? Вроде бы это отлавливает и null, и undefined, но что насчёт пустой строки или числа 0? Они ведь тоже falsy-значения. Не вызовет ли это баги? И ещё: есть ли разница между `value == null` и `value === null || value === undefined`? Я читал, что `==` может приводить типы, но в случае с null это безопасно? Буду благодарен за подробное объяснение с примерами. Спасибо! <<>>

Основной способ: оператор строгого неравенства (не рекомендуется)

Самый явный, но громоздкий способ, который вы уже привели:

if (value !== null && value !== undefined) {
  // value точно не null и не undefined
}

Он работает, но в TypeScript есть гораздо более элегантные решения.

Лучший способ: оператор `!= null` (строгое сравнение с null через `==`)

Да, вы всё верно подозревали. В JavaScript/TypeScript оператор == при сравнении с null ведёт себя особенным образом: null == undefined возвращает true. Поэтому можно писать так:

if (value != null) {
  // value не null И не undefined
  console.log(value.toUpperCase()); // TypeScript это поймёт
}

Это самый популярный и рекомендуемый способ в TypeScript. Он короткий, читаемый и корректно работает с типами.

Почему нельзя писать просто `if (value)`?

Вы правы: это отловит null и undefined, но также отловит и другие falsy-значения:

  • 0 (число ноль)
  • "" (пустая строка)
  • false
  • NaN

Пример проблемы:

function getLength(value: string | null | undefined) {
  if (value) {
    return value.length; // Ошибка! Если value = "", то length не вернётся
  }
  return 0;
}

console.log(getLength("")); // Вернёт 0, хотя длина пустой строки — 0!

Поэтому if (value) стоит использовать только когда вы точно знаете, что falsy-значения недопустимы (например, для проверки наличия объекта).

Оператор `??` (nullish coalescing)

Вы упомянули ??. Он не проверяет, а заменяет значение, если оно null или undefined:

const safeValue = value ?? "значение по умолчанию";
// Если value — null или undefined, то safeValue = "значение по умолчанию"
// Иначе safeValue = value (даже если value = 0, false или "")

Это отличный оператор, но он не делает проверку — он подставляет дефолт. Если вам нужно просто проверить и выполнить действие, используйте != null.

TypeScript: type guard с помощью `typeof`

Иногда вам нужно отличить undefined от null. Для этого используйте typeof:

if (value === undefined) {
  console.log('Это именно undefined');
} else if (value === null) {
  console.log('Это именно null');
} else {
  console.log(value.toUpperCase()); // Остальные случаи
}

Итоговые рекомендации

  • Для простой проверки на null/undefined: используйте value != null
  • Для замены на значение по умолчанию: используйте value ?? default
  • Избегайте if (value) если возможны falsy-значения (0, "", false)
  • Для точного различения используйте === undefined или === null

TypeScript правильно понимает все эти проверки и сужает типы. Например, после if (value != null) внутри блока TypeScript будет знать, что value — точно не null и не undefined.

<<>>

Альтернативный подход: функция-хелпер

Если вы часто проверяете на null/undefined, можно вынести проверку в отдельную функцию:

function isNotNullOrUndefined<T>(value: T | null | undefined): value is T {
  return value != null;
}

// Использование:
if (isNotNullOrUndefined(value)) {
  console.log(value.toUpperCase()); // TypeScript знает, что value — не null/undefined
}

Этот подход особенно полезен в цепочках фильтрации массивов:

const items: (string | null | undefined)[] = ["a", null, "b", undefined];
const cleanItems = items.filter(isNotNullOrUndefined); // Тип: string[]

Использование Optional Chaining (?.)

Для доступа к свойствам или методам объекта, который может быть null/undefined, используйте оператор ?.:

const user = { name: "Alice", address: null };
const city = user.address?.city; // Без ошибки, вернёт undefined

Комбинация ?. и ?? даёт очень чистый код:

const city = user.address?.city ?? "город не указан";

Когда использовать какой способ?

  • Простая проверка в if: value != null
  • Доступ к вложенным свойствам: obj?.prop
  • Значение по умолчанию: value ?? default
  • Часто повторяющаяся проверка: функция-хелпер с type guard

Все эти инструменты делают код на TypeScript безопасным и лаконичным. Не бойтесь использовать != null — это идиоматический способ, принятый в сообществе.