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

Коли оператор ! (non-null assertion) доречний, а коли він приховує помилку?

Постфіксний ! каже компілятору: «це значення точно не null і не undefined». Компілятор вірить на слово й прибирає null | undefined з типу.

const input = document.querySelector('#email')!;   // HTMLElement замість HTMLElement | null
const price = prices.get('coffee')!;               // number замість number | undefined

! нічого не перевіряє під час виконання. Якщо значення все ж null, помилка виникне пізніше й далеко від причини: Cannot read properties of null. TypeScript саме для того й попереджав.

Коли ! доречний:

  • значення гарантовано існує з причин, яких компілятор не бачить, і ця гарантія очевидна поруч у коді;
  • ініціалізація, яку TypeScript не відстежує (поле класу, яке заповнює фреймворк), - хоча для полів краще field!: Type у оголошенні з коментарем, ніж ! при кожному використанні.

Краще альтернативи в більшості випадків:

  • явна перевірка з помилкою - падіння одразу з зрозумілим текстом:
const input = document.querySelector<HTMLInputElement>('#email');
if (!input) throw new Error('Поле #email не знайдено');
input.value;   // тут уже HTMLInputElement
  • функція-помічник:
function assertDefined<T>(value: T, message: string): asserts value is NonNullable<T> {
  if (value == null) throw new Error(message);
}
  • опціональний ланцюжок і значення за замовчуванням, якщо відсутність нормальна: prices.get('coffee') ?? 0;
  • переписати код так, щоб тип був точним: зберігати знайдений елемент у змінній після перевірки, а не шукати двічі.

Типові місця, де ! приховує баги:

  • map.get(key)! - ключа може не бути;
  • array.find(...)! - елемента може не знайтися;
  • useRef<HTMLDivElement>(null).current! в ефекті, що може виконатися до монтування;
  • process.env.API_KEY! - змінну оточення можуть не задати.

Лінтер (@typescript-eslint/no-non-null-assertion) змушує обґрунтовувати кожен ! - корисне правило для команди.

Важливо: strict у TypeScript 6+ увімкнено за замовчуванням, тож перевірки на null діють навіть без явного "strict": true - і ! стає помітнішою «дірою» в цих перевірках.

Докладніше в документації: Оператор non-null assertion

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