Иногда вы знаете о структуре данных больше, чем компилятор TypeScript. В режиме строгой проверки null (strictNullChecks) компилятор может выдавать ошибку «Object is possibly 'null' or 'undefined'», даже если вы уверены, что значение существует.
Для таких случаев существует оператор Non-null assertion — восклицательный знак (!) после выражения. Он говорит компилятору: «Я гарантирую, что здесь нет null или undefined, не проверяй это». Используйте этот оператор осторожно, так как он отключает защиту только на этапе компиляции, но не страхует от ошибок во время выполнения.
- Модуль 1: Введение в TypeScript
- Модуль 2: Примитивные типы
- Модуль 3: Специальные типы
- Модуль 4: Массивы
- Модуль 5: Кортежи (Tuples)
- Модуль 6: Объекты
- Модуль 7: Функции
- Модуль 8: Union типы
- Модуль 9: Литеральные типы
- Модуль 10: Type Aliases
- Модуль 11: Интерфейсы
- Модуль 12: Type Guards и Narrowing
- Модуль 13: Enums
- Модуль 14: Классы
- Модуль 15: Generics — основы
- Модуль 16: Generics — ограничения
- Модуль 17: Utility Types — базовые
- Модуль 18: Utility Types — работа с Union
- Модуль 19: Utility Types — функции
- Модуль 20: Type Assertions
- Утверждение типа (as).
- Угловые скобки ().
- Non-null assertion (!).
- as const.
- Двойное утверждение (as unknown as T).
- Модуль 21: Keyof и Typeof операторы
- Модуль 22: Mapped Types
- Модуль 23: Conditional Types
- Модуль 24: Discriminated Unions
- Модуль 25: Модули и типы
- Модуль 26: Declaration Files
- Модуль 27: Типизация асинхронного кода
- Модуль 28: Практические паттерны
1. Поиск оператора assertion
В данном фрагменте кода TypeScript, работающего с DOM-элементами, найдите и отметьте все места, где используется оператор non-null assertion (символ `!`). Этот оператор указывает компилятору, что выражение не является null или undefined. Не отмечайте имена переменных, методы, строковые литералы или другие элементы кода — только сам оператор `!`.
const input = {{document~|~t3}}.{{getElementById~|~t4}}('{{myInput~|~t5}}'){{!~|~t1}};
const value = input.value;
const button = {{document~|~t6}}.{{querySelector~|~t7}}('{{button~|~t8}}'){{!~|~t2}};
button.{{addEventListener~|~t9}}('{{click~|~t10}}', () => {
{{console~|~t11}}.{{log~|~t12}}(value);
});
const maybeNull = document.getElementById('nonexistent');
if (maybeNull) {
maybeNull.classList.add('active');
}2. Устранение ошибки компиляции
В этом фрагменте кода TypeScript переменная `userName` имеет тип `string | null`. При попытке вызвать метод `toUpperCase()` для этой переменной возникает ошибка компиляции, так как метод не может быть вызван для значения, которое может быть `null`. Используйте оператор non-null assertion, чтобы указать компилятору, что в данном месте переменная точно не равна `null`. Вставьте соответствующий оператор в отмеченное место, чтобы код успешно компилировался и выводил приветствие в верхнем регистре.
let userName: string | null = "Alice";
// В реальном приложении значение может прийти извне и быть null
// Используйте non-null assertion, чтобы указать, что переменная не равна null
let greeting: string = `Hello, ${userName input1S.toUpperCase()}!`;
console.log(greeting);3. Безопасность кода
Сопоставьте фрагменты кода TypeScript из левой колонки с соответствующими описаниями безопасности из правой колонки. Каждый фрагмент демонстрирует подход к работе с потенциально null/undefined значениями. Обратите внимание на различия в гарантиях безопасности во время компиляции и выполнения.
if (element !== null) {
console.log(element.value);
}console.log(element!.value);4. Риск Runtime ошибки
В данном задании представлен фрагмент кода на TypeScript, в котором используется оператор non-null assertion (!) для значения, объявленного как потенциально null. Ваша задача - внимательно проанализировать код и предсказать, что произойдет при его выполнении: возникнет ли ошибка TypeError (из-за попытки доступа к свойству или методу null) или код выполнится успешно. Обратите внимание, что non-null assertion не добавляет проверок во время выполнения, а только влияет на проверку типов при компиляции.
let value: string | null = null;
console.log(value!.toUpperCase());5. Выбор оператора
В этом задании вам предстоит заполнить пропуски в коде TypeScript, выбирая между оператором опциональной цепочки `?.` и оператором non-null assertion `!`. В зависимости от контекста, вам нужно решить, следует ли безопасно обрабатывать возможные значения null/undefined (возвращая undefined) или утверждать, что значение гарантированно существует (рискуя получить ошибку времени выполнения). Обратите внимание на типы переменных и контекст их использования.
interface User {
name: string;
address?: {
street: string;
city: string;
};
}
function getUser(): User | null {
// Возвращает User или null
return Math.random() > 0.5 ? { name: 'Alice', address: { street: 'Main St', city: 'Town' } } : null;
}
const user = getUser();
// Безопасное получение свойства, если user может быть null
const userName = user input1S name;
// Безопасный доступ к вложенному свойству, если address может быть undefined
const city = user input2S address input3S city;
// Утверждение, что user не null (если мы уверены в этом после проверки)
const street = user! input4S address input5S street;
// Пример с массивом, который может быть undefined
const tags: string[] | undefined = undefined;
const firstTag = tags input6S 0;6. Логика проверки
Проанализируйте TypeScript-код сверху и восстановите последовательность логических шагов выполнения программы. Шаги снизу перемешаны — расставьте их в правильном порядке, чтобы отразить, как программа получает элемент DOM, использует non-null assertion для гарантии его существования и изменяет его стиль.
function highlightElement(id: string): void {
const element = document.getElementById(id)!;
element.style.backgroundColor = 'yellow';
}
// Вызов функции с конкретным id
highlightElement('myDiv');7. Результат выражения
В приведённом фрагменте кода TypeScript определён объект с опциональными полями. Используется оператор non-null assertion (!) для доступа к значению одного из полей. Определите, какое значение будет выведено в консоль после выполнения кода. Введите одно число или строку (в зависимости от результата) без дополнительных символов.
interface User {
id?: number;
username?: string;
}
const currentUser: User = {
id: 101,
username: "alex_ts"
};
const userId = currentUser.id!;
const userName = currentUser.username!;
console.log(userId + userName.length);