Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працює опціональний ланцюжок ?. і де він може приховати помилку?

Оператор ?. звертається до властивості чи викликає метод, лише якщо значення ліворуч не null і не undefined. Інакше весь вираз повертає undefined замість TypeError.

const city = order?.customer?.address?.city;

// раніше
const city = order && order.customer && order.customer.address && order.customer.address.city;

Три форми:

user?.name             // властивість
user?.['first-name']   // обчислена властивість чи індекс
callback?.()           // виклик, якщо функція існує
user.save?.()          // виклик методу, якщо він є

Коротке замикання. Якщо ?. зустрів null/undefined, решта ланцюжка не обчислюється:

null?.a.b.c;               // undefined, а не TypeError на .b
user?.profile.update(log()); // log() не викликається, якщо user - null

Поєднання з ?? - значення за замовчуванням:

const theme = settings?.ui?.theme ?? 'light';
const total = response?.meta?.total ?? 0;

Обмеження:

  • ліворуч від присвоєння не працює: user?.name = 'Оля' - синтаксична помилка;
  • з new не працює: new Foo?.();
  • ?.() захищає лише від null/undefined, а не від «не функції»: { f: 42 }.f?.() кине TypeError: f is not a function.

Де ?. приховує помилки:

function renderInvoice(order) {
  const total = order?.items?.reduce((sum, item) => sum + item.price, 0);
  return `Разом: ${total} грн`;   // 'Разом: undefined грн'
}

Якщо order не повинен бути порожнім, ?. ховає баг: замість зрозумілої помилки в місці, де дані зламалися, отримуємо undefined у інтерфейсі чи NaN у розрахунку - далеко від справжньої причини.

Правило: ?. - для значень, відсутність яких очікувана й нормальна (необов'язкові поля API, опційні колбеки, елемент, якого може не бути на сторінці). Для обов'язкових даних краще явна перевірка з помилкою на вході:

if (!order) throw new Error('Замовлення не завантажено');

TypeScript робить це правило природним: для необов'язкових типів (address?: Address) він вимагає ?., а для обов'язкових - не дозволяє безпідставно сподіватися на «а раптом там null».

Аналог у PHP 8 - nullsafe-оператор $order?->customer?->address.

Докладніше в документації: Optional chaining

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання