Это определено в спецификации ECMAScript Optional Chaining, поэтому мы должны, вероятно, сослаться на опциональную цепочку , когда мы обсудим это. Вероятная реализация:
const result = a?.b?.c;
Длинным и коротким из этого является то, что команда TypeScript ожидает, что спецификация ECMAScript будет затянута, поэтому их реализация может быть неразрывной в будущем. Если они что-то реализуют сейчас, в случае необходимости ECMAScript потребует серьезных изменений, если ECMAScript переопределит их спецификацию.
См. Дополнительная спецификация цепочки
Где-то никогда не будет быть стандартным JavaScript, команда TypeScript может реализовать по своему усмотрению, но для будущих дополнений ECMAScript они хотят сохранить семантику, даже если они дают ранний доступ, как и для многих других функций.
Таким образом, доступны все java-скрипты JavaScripts, включая преобразования типов, такие как ...
var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
Но вернемся к вопросу. У меня есть тупой пример того, как вы можете сделать аналогичную вещь в JavaScript (и, следовательно, в TypeScript), хотя я определенно не предполагаю, что это изящно, как функция, которую вы действительно выполняете.
(foo||{}).bar;
So если foo
- undefined
, результат будет undefined
, и если foo
определено и имеет свойство с именем bar
, которое имеет значение, результатом будет это значение.
Пример в JSFiddle .
Это выглядит довольно отрывочно для более длинных примеров.
var postCode = ((person||{}).address||{}).postcode;
Если вы отчаянно нуждаетесь в более короткая версия, пока спецификация все еще находится в воздухе, я использую этот метод в некоторых случаях. Он оценивает выражение и возвращает значение по умолчанию, если цепочка не может быть удовлетворена или заканчивается нулевым / неопределенным (обратите внимание, что !=
здесь важна, мы не хотим использовать !==
как мы хотим немного позитивного манипулирования здесь).
function chain(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'));
Довольно часто передается цель (здесь ваш VC) и селектор (обработчик method), когда вам нужен обратный вызов и вы не хотите переходить к вызывающему методу обработчика. Это называется шаблоном выбора цели.
Кроме того, вы можете проверить фреймворки RestfulCoreData и CoreResource , чтобы узнать о возможных вариантах этого.
Также известная структура ObjectiveResource может дать хорошее представление.