Це визначено в специфікації додаткового ланцюга ECMAScript, тому ми, мабуть, повинні посилатися на необов'язкові ланцюжки, коли ми обговорюємо це. Ймовірна реалізація:
const result = a?.b?.c;
Довгий і короткий у цьому випадку полягає в тому, що команда TypeScript чекає посилення специфікації ECMAScript, тому в майбутньому їх реалізація може бути непорушною. Якщо вони щось реалізували зараз, вони, в кінцевому рахунку, потребують великих змін, якщо ECMAScript перегляне їх специфікацію.
Див. Додаткову специфікацію ланцюга
Якщо щось ніколи не буде стандартним JavaScript, команда TypeScript може реалізовувати, як вважає за потрібне, але для майбутніх доповнень ECMAScript вони хочуть зберегти семантику, навіть якщо вони надають ранній доступ, як у них для багатьох інших функцій.
Короткі вирізи
Таким чином, всі функціональні оператори JavaScripts доступні, включаючи перетворення типу, такі як ...
var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
Ручне рішення
Але повернемось до питання. У мене є чіткий приклад того, як ви можете робити подібну річ в JavaScript (і, отже, TypeScript), хоча я точно не припускаю, що це витончена функція, яку ви справді шукаєте.
(foo||{}).bar;
Так що, якщо fooє undefinedрезультат , undefinedі якщо fooвизначений і має ім'я властивістьbar , який має значення, в результаті чого значення.
Я ставлю приклад на JSFiddle .
Це виглядає досить схематично для довших прикладів.
var postCode = ((person||{}).address||{}).postcode;
Функція ланцюга
Якщо ви відчайдушно ставитеся до коротшої версії, поки специфікація все ще в повітрі, я використовую цей метод у деяких випадках. Він оцінює вираз і повертає за замовчуванням, якщо ланцюг не може бути задоволений або закінчується нульовим / невизначеним (зауважте, що !=тут важливо, ми не хочемо використовувати, !==оскільки тут хочеться трохи позитивного жонглювання).
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'));