Non-Null Assertion Operator (!) — это специальный синтаксис TypeScript, позволяющий явно сказать компилятору: "Я знаю, что переменная к этому моменту не равна null или undefined". Оператор добавлен для решения типовых проблем в сценариях, когда программист уверен в существовании значения, но TypeScript не может этого гарантировать из-за своего строгого анализа.
TypeScript строго относится к возможности переменных быть null или undefined, особенно при включённой опции strictNullChecks. Чтобы избавиться от предупреждений компилятора в ситуациях, где программист уверен в безопасности значения, ввели non-null assertion.
TypeScript не всегда может отследить все ветки кода и понять, что условие реже null выполнять не нужно. Это часто случается после асинхронного кода, в колбэках, при обработке DOM-элементов.
Non-Null Assertion Operator (!) сообщает компилятору об отсутствии null/undefined в данном месте, убирая ошибку типов.
Пример кода:
function processUser(user?: {name: string}) { // TS выдаст ошибку без оператора: user может быть undefined console.log(user!.name); // Оператор ! обещает, что user определён }
Ключевые особенности:
Можно ли использовать ! для любого значения любого типа? Например: let x: number = y!
Оператор ! имеет смысл только для типов, потенциально содержащих null/undefined по мнению компилятора. Для строго типизированных переменных без nullable не даёт эффекта.
Заменяет ли ! проверку на null/undefined полностью? Нужно ли делать runtime-проверку?
Нет, оператор ! не выполняет проверки на время исполнения. Он помогает только компилятору и если реальное значение окажется undefined/null, произойдёт ошибка времени выполнения.
function foo(data?: string) { // может привести к ошибке alert(data!.length); }
Может ли ! спасти от ошибок в асинхронном коде, если исходная переменная меняется в другом потоке?
Нет. Оператор ! работает только в точке применения. Если между проверкой и использованием значение стало undefined, ошибки не избежать. Всегда нужно быть уверенным в актуальности не-null-ности.
Внутри компонента React обращаются к DOM через ref с !-оператором без предварительной проверки:
const ref = useRef<HTMLDivElement>(null); ref.current!.focus(); // если ref.current null, будет runtime-ошибка
Плюсы:
Минусы:
Использование проверки на существование перед применением:
if (ref.current) { ref.current.focus(); }
Плюсы:
Минусы: