Jest to zdefiniowane w specyfikacji opcjonalnego łańcucha ECMAScript, więc prawdopodobnie powinniśmy odwoływać się do opcjonalnego łańcucha podczas omawiania tego. Prawdopodobne wdrożenie:
const result = a?.b?.c;
Krótko mówiąc o tym, że zespół TypeScript czeka na doprecyzowanie specyfikacji ECMAScript, więc ich implementacja może być niezłomna w przyszłości. Gdyby coś zaimplementowali teraz, skończyłoby się to poważnymi zmianami, gdyby ECMAScript przedefiniował ich specyfikację.
Zobacz opcjonalną specyfikację łączenia
Tam, gdzie coś nigdy nie będzie standardowym skryptem JavaScript, zespół TypeScript może wdrożyć, co uzna za stosowne, ale w przypadku przyszłych dodatków ECMAScript chcą zachować semantykę, nawet jeśli dają wczesny dostęp, tak jak w przypadku wielu innych funkcji.
Short Cuts
Dostępne są więc wszystkie operatory JavaScript w funky, w tym konwersje typów, takie jak ...
var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
Rozwiązanie ręczne
Ale wracając do pytania. Mam tępy przykład tego, jak możesz zrobić podobną rzecz w JavaScript (i dlatego TypeScript), chociaż zdecydowanie nie sugeruję, że jest to wdzięczne, ponieważ funkcja, której naprawdę szukasz.
(foo||{}).bar;
Więc jeśli foo
to undefined
wynik jest undefined
i jeśli foo
jest zdefiniowany i ma właściwość o nazwie bar
, która ma wartość, wynik jest, że wartość.
I umieścić przykład na JSFiddle .
Wygląda to dość szkicowo w przypadku dłuższych przykładów.
var postCode = ((person||{}).address||{}).postcode;
Funkcja łańcucha
Jeśli desperacko oczekujesz krótszej wersji, gdy specyfikacja wciąż jest w powietrzu, w niektórych przypadkach używam tej metody. Ocenia wyrażenie i zwraca wartość domyślną, jeśli łańcuch nie może być spełniony lub kończy się na wartości zerowej / niezdefiniowanej (zwróć uwagę, że !=
tutaj jest to ważne, nie chcemy używać, !==
ponieważ chcemy tutaj trochę pozytywnego żonglowania).
function chain<T>(exp: () => T, d: T) {
try {
let val = exp();
if (val != null) {
return val;
}
} catch { }
return d;
}
let obj1: { a?: { b?: string }} = {
a: {
b: 'c'
}
};
// 'c'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {
a: {}
};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = {};
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
obj1 = null;
// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));