Mechanizm optional chaining (?.) pojawił się w JavaScript, aby umożliwić bezpieczny dostęp do właściwości i metod obiektów, które mogą być opcjonalnie zdefiniowane. W TypeScript stał się szczególnie przydatny, ponieważ pomaga unikać błędów w czasie wykonywania związanych z dostępem do właściwości lub metod undefined lub null.
Przed pojawieniem się optional chaining programiści musieli ręcznie sprawdzać istnienie każdego poziomu zagnieżdżenia obiektu, co sprawiało, że kod był długi i trudny do odczytania:
if (obj && obj.a && obj.a.b) { // ... }
Przy dostępie do zagnieżdżonych właściwości obiektu, który jest undefined, może wystąpić błąd czasu wykonywania: Cannot read property 'x' of undefined. Ponadto długie łańcuchy sprawdzeń utrudniają utrzymanie i zrozumienie kodu.
Optional chaining (?.) pozwala na dostęp do zagnieżdżonych właściwości, metod lub elementów tablicy, automatycznie zwracając undefined, jeśli któraś część łańcucha jest równa null lub undefined.
Przykład kodu:
interface User { name: string; address?: { city?: string; }; } const user: User = { name: 'Ivan' }; console.log(user.address?.city); // undefined
Kluczowe cechy:
T | undefined, co jest uwzględniane przez kompilator TypeScript i pomaga unikać błędów.Czy można użyć optional chaining po lewej stronie operatora przypisania? Na przykład: user.address?.city = 'Moscow'?
Nie, optional chaining nie może być używane w lewym wyrażeniu przypisania, spowoduje to błąd kompilacji. Optional chaining działa tylko przy odczycie, a nie przy zapisie.
Czy można skorzystać z optional chaining do wywołania metody, jeśli sam obiekt może być niezdefiniowany? Na przykład: user?.logInfo()?
Tak, jeśli obiekt przed punktem wywołania metody może być undefined/null, to wywołanie user?.logInfo() nie spowoduje błędu i po prostu zwróci undefined, jeśli user nie jest zdefiniowany.
user?.logInfo(); // jeśli user jest zdefiniowany, wywoła logInfo, w przeciwnym razie nic się nie stanie
Jaka jest różnica między optional chaining a operatorem '&&' w tradycyjnym stylu, na przykład: user && user.address && user.address.city?
Optional chaining jest krótszy, działa dla wszystkich typów (w tym metod i tablic) oraz TypeScript uwzględnia go w sprawdzaniu typów. Ważne jest, że przy użyciu operatora '&&' możesz przypadkowo uzyskać wartość zagnieżdżoną, a nie true/false lub undefined. Optional chaining z góry daje oczekiwany typ albo undefined, co jest uwzględniane w wnioskowaniu typów.
W kodzie używane są długie łańcuchy optional chaining nawet tam, gdzie zmienne według logiki biznesowej są zawsze zdefiniowane:
order?.customer?.address?.city = 'London';
Zalety:
Wady:
Optional chaining jest używane tylko przy pracy z danymi zewnętrznymi lub w miejscach, gdzie wartości mogą być naprawdę niezdefiniowane:
const city = apiResponse?.info?.location?.city || 'Unknown';
Zalety:
Wady: