Поддерживает ли TypeScript оператор ?. и как он правильно называется?
Что такое оператор ?. (опциональная цепочка) в TypeScript?
Да, TypeScript полностью поддерживает оператор ?., который называется опциональная цепочка (optional chaining). Этот оператор был представлен в TypeScript 3.7 и с тех пор является стандартной частью языка. Важно понимать, что это не только фича TypeScript — это нативная возможность JavaScript, начиная с ES2020. TypeScript просто добавляет к ней строгую типизацию.
Как это работает?
Оператор ?. позволяет безопасно обращаться к вложенным свойствам объекта, не проверяя каждое промежуточное значение на null или undefined. Если какая-либо часть цепочки оказывается null или undefined, то выражение сразу возвращает undefined, не вызывая ошибки.
Рассмотрим ваш пример:
interface User {
profile?: {
name?: string;
};
}
const user: User = {};
console.log(user?.profile?.name); // Выведет: undefined
Без ?. вы бы получили ошибку, так как user.profile — это undefined, и попытка обратиться к .name у undefined вызовет исключение. С опциональной цепочкой код безопасен.
Где можно использовать ?.
- Свойства объектов:
obj?.prop - Индексы массивов:
arr?.[index] - Вызов функций:
func?.(args)— вызывает функцию только если она существует
Примеры с функциями
Опциональная цепочка работает и с вызовом функций. Это полезно, когда вы не уверены, что метод существует:
interface ApiResponse {
data?: {
items?: Array<{ id: number }>;
getItem?: (id: number) => { id: number } | undefined;
};
}
const response: ApiResponse = {};
// Безопасный вызов метода
const item = response.data?.getItem?.(5);
console.log(item); // undefined, но ошибки не будет
// Безопасный доступ к элементу массива
const firstItem = response.data?.items?.[0];
console.log(firstItem); // undefined
Разница между ?. и !. (non-null assertion)
Важно не путать опциональную цепочку с оператором ! (non-null assertion). ! говорит TypeScript: "Я уверен, что это значение не null и не undefined", но не добавляет никакой проверки в рантайме:
// Опасно! Если profile = undefined, код упадет
console.log(user.profile!.name); // Ошибка в рантайме, если profile нет
// Безопасно
console.log(user.profile?.name); // Просто вернет undefined
Комбинация с оператором ?? (nullish coalescing)
Часто ?. используют вместе с ?? (оператор нулевого слияния), чтобы задать значение по умолчанию:
const userName = user?.profile?.name ?? 'Гость';
console.log(userName); // 'Гость', так как profile.name = undefined
Ограничения
Опциональную цепочку нельзя использовать для левой части присваивания. Например, user?.name = 'John' вызовет ошибку. Также будьте осторожны с производительностью в циклах — каждая проверка добавляет небольшой overhead, но в 99% случаев это несущественно.
В итоге, ?. — это мощный инструмент для написания чистого и безопасного кода. Используйте его вместо длинных цепочек if-проверок, и ваш код станет гораздо читаемее.
Альтернативный подход: логические операторы и утилитарные функции
Хотя опциональная цепочка — это современный и удобный способ, вы можете столкнуться с кодом, где её не используют, особенно в старых проектах или если нужно поддерживать очень старые версии JavaScript (до ES2020). В таких случаях применяют традиционные проверки:
// Старый способ с логическими операторами
const userName = user && user.profile && user.profile.name || 'Гость';
// Или более читаемый вариант с if
let userName = 'Гость';
if (user && user.profile && user.profile.name) {
userName = user.profile.name;
}
Также можно написать вспомогательную функцию для глубокого доступа:
function getSafe(obj: any, path: string, defaultValue?: any): any {
return path.split('.').reduce((acc, key) => {
return acc && acc[key] !== undefined ? acc[key] : undefined;
}, obj) ?? defaultValue;
}
const name = getSafe(user, 'profile.name', 'Гость');
Этот подход более гибкий, но менее производительный и читаемый. Рекомендую использовать ?. везде, где это возможно, так как это стандарт современного TypeScript и JavaScript.
Ответов пока нет.
Войдите чтобы оставить ответ