Dies ist in der Spezifikation für die optionale Verkettung von ECMAScript definiert. Daher sollten wir uns bei der Erörterung wahrscheinlich auf die optionale Verkettung beziehen . Voraussichtliche Umsetzung:
const result = a?.b?.c;
Das lange und kurze daran ist, dass das TypeScript-Team darauf wartet, dass die ECMAScript-Spezifikation verschärft wird, damit ihre Implementierung in Zukunft nicht mehr unterbrochen werden kann. Wenn sie jetzt etwas implementieren würden, müssten größere Änderungen vorgenommen werden, wenn ECMAScript ihre Spezifikation neu definiert.
Siehe Optionale Verkettungsspezifikation
Wenn etwas niemals Standard-JavaScript sein wird, kann das TypeScript-Team es nach eigenem Ermessen implementieren. Für zukünftige ECMAScript-Ergänzungen möchten sie jedoch die Semantik beibehalten, auch wenn sie wie bei so vielen anderen Funktionen frühzeitig darauf zugreifen.
Abkürzungen
So sind alle funky JavaScripts-Operatoren verfügbar, einschließlich der Typkonvertierungen wie ...
var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
Manuelle Lösung
Aber zurück zur Frage. Ich habe ein stumpfes Beispiel dafür, wie Sie in JavaScript (und damit in TypeScript) etwas Ähnliches tun können, obwohl ich definitiv nicht vorschlage, dass es eine anmutige Funktion ist, nach der Sie wirklich suchen.
(foo||{}).bar;
Wenn foo
also undefined
das Ergebnis ist undefined
und wenn foo
definiert ist und eine Eigenschaft bar
mit einem Wert hat, ist das Ergebnis dieser Wert.
Ich habe ein Beispiel für JSFiddle gegeben .
Dies sieht für längere Beispiele recht lückenhaft aus.
var postCode = ((person||{}).address||{}).postcode;
Kettenfunktion
Wenn Sie verzweifelt nach einer kürzeren Version suchen, während die Spezifikation noch in der Luft ist, verwende ich diese Methode in einigen Fällen. Es wertet den Ausdruck aus und gibt einen Standardwert zurück, wenn die Kette nicht erfüllt werden kann oder null / undefiniert endet (beachten Sie !=
, dass dies hier wichtig ist, wir möchten es nicht verwenden, !==
da wir hier ein bisschen positives Jonglieren wollen).
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'));