Wie bereits erwähnt, wird derzeit noch darüber nachgedacht, aber es ist bereits seit einigen Jahren eingefroren.
Aufbauend auf den vorhandenen Antworten, hier ist die prägnanteste manuelle Version, die mir einfällt:
jsfiddle
function val(valueSupplier: () => T): T {
try { return valueSupplier(); } catch (err) { return undefined; }
}
let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(val(() => obj1.a.b)); // 'c'
obj1 = { a: {} };
console.log(val(() => obj1.a.b)); // undefined
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'
obj1 = {};
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'
obj1 = null;
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'
Es scheitert einfach still bei fehlenden Eigenschaftsfehlern. Es greift auf die Standard-Syntax zurück, um den Standardwert zu bestimmen, der auch komplett weggelassen werden kann.
Obwohl dies für einfache Fälle funktioniert, werden bei komplexeren Dingen wie dem Aufruf einer Funktion und anschließendem Zugriff auf eine Eigenschaft des Ergebnisses auch andere Fehler verschluckt. Schlechtes Design.
In dem obigen Fall ist eine optimierte Version der anderen hier geposteten Antwort die bessere Option:
jsfiddle
function o(obj?: T, def: T = {} as T): T {
return obj || def;
}
let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(o(o(o(obj1).a)).b); // 'c'
obj1 = { a: {} };
console.log(o(o(o(obj1).a)).b); // undefined
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'
obj1 = {};
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'
obj1 = null;
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'
Ein komplexeres Beispiel:
o(foo(), []).map((n) => n.id)
Sie können auch den anderen Weg gehen und etwas wie Lodash' _.get()
verwenden. Es ist prägnant, allerdings kann der Compiler die Gültigkeit der verwendeten Eigenschaften nicht beurteilen:
console.log(_.get(obj1, 'a.b.c'));