Поддерживает ли Typescript. оператор? (И как это называется?)
В настоящее время Typescript (или есть планы) поддерживает безопасного судоходства оператор ?.
ie:
var thing = foo?.bar
// same as:
var thing = (foo) ? foo.bar : null;
кроме того, есть ли более распространенное имя для этого оператора (его невозможно найти в google).
10 ответов:
Я не могу найти никаких ссылок на него вообще в спецификация языка машинописи.
что касается того, как назвать этот оператор в CoffeeScript, он называется оператор экзистенциальной (в частности, "вариант доступа" экзистенциального оператора).
С документация CoffeeScript по операторам:
вариант доступа экзистенциального оператора
?.может использоваться для впитывания пустые ссылки в цепочке свойств. Используйте его вместо точки доступа.в случаях, когда базовое значение может быть null или неопределено.Итак,вариант доступа экзистенциального оператора представляется правильным способом ссылаться на этот оператор; и TypeScript в настоящее время не поддерживает его (Хотя другие выразили желание для этой функциональности).
не так хорошо, как один ? но это работает:
var thing = foo && foo.bar || null;Вы можете использовать столько && как вам нравится:
var thing = foo && foo.bar && foo.bar.check && foo.bar.check.x || null;
это определено в спецификации ECMAScript Optional Chaining, поэтому мы, вероятно, должны обратиться к дополнительные цепочки когда мы обсуждаем это. Вероятная реализация:
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это имеет значение, результат - это значение.I поставьте пример на JSFiddle.
это выглядит довольно схематично для уже примеров.
var postCode = ((person||{}).address||{}).postcode;Функции Цепи
если вы отчаянно нуждаетесь в более короткой версии, пока спецификация все еще находится в воздухе, я использую этот метод в некоторых случаях. Он вычисляет выражение и возвращает значение по умолчанию, если цепочка не может быть удовлетворена или заканчивается null / undefined (обратите внимание на
!=здесь важно, мы не хотите использовать!==как мы хотим немного позитивного жонглирования здесь).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'));
есть открытый запрос функции для этого на github, где вы можете высказать свое мнение / желание:https://github.com/Microsoft/TypeScript/issues/16
Edit: я обновил ответ благодаря комментарию fracz.
TypeScript 2.0 выпущен
!.Это не то же самое как?.(Безопасный навигатор в C#)посмотреть этот ответ для более подробной информации:
https://stackoverflow.com/a/38875179/1057052
Это только говорит компилятору, что значение не является null или undefined. Это будет не проверить, если значение null или undefined.
TypeScript оператор ненулевого утверждения
// Compiled with --strictNullChecks function validateEntity(e?: Entity) { // Throw exception if e is null or invalid entity } function processEntity(e?: Entity) { validateEntity(e); let s = e!.name; // Assert that e is non-null and access name }
оператор
?.не поддерживается в TypeScript версия 2.0.поэтому я использую следующую функцию:
export function o<T>(someObject: T, defaultValue: T = {} as T) : T { if (typeof someObject === 'undefined' || someObject === null) return defaultValue; else return someObject; }использование выглядит так:
o(o(o(test).prop1).prop2плюс, вы можете установить значение по умолчанию:
o(o(o(o(test).prop1).prop2, "none")Он очень хорошо работает с IntelliSense в Visual Studio.
мы создали этот метод util во время работы над Phonetradr который может дать вам типобезопасный доступ к глубоким свойствам с помощью Typescript:
/** * Type-safe access of deep property of an object * * @param obj Object to get deep property * @param unsafeDataOperation Function that returns the deep property * @param valueIfFail Value to return in case if there is no such property */ export function getInSafe<O,T>(obj: O, unsafeDataOperation: (x: O) => T, valueIfFail?: any) : T { try { return unsafeDataOperation(obj) } catch (error) { return valueIfFail; } } //Example usage: getInSafe(sellTicket, x => x.phoneDetails.imeiNumber, ''); //Example from above getInSafe(foo, x => x.bar.check, null);
как было сказано ранее, в настоящее время он все еще рассматривается, но это был мертв в воде уже несколько лет.
основываясь на существующих ответах, вот самый краткий руководство версия, которую я могу придумать:
function val<T>(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'Он просто молча терпит неудачу при отсутствии ошибок свойств. Он возвращается к стандартному синтаксису для определения значения по умолчанию, которое может быть полностью опущено как что ж.
хотя это работает для простых случаев, если вам нужны более сложные вещи, такие как вызов функции, а затем доступ к свойству на результат, то любые другие ошибки также проглатываются. Плохой дизайн.
в приведенном выше случае оптимизированная версия другого ответа, опубликованного здесь, является лучшим вариантом:
function o<T>(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'более сложный пример:
o(foo(), []).map((n) => n.id)
вы также можете пойти другой способ и использовать что-то вроде Lodash'
_.get(). Он лаконичен, но компилятор не сможет судить о достоверности используемых свойств:console.log(_.get(obj1, 'a.b.c'));
Follow up @VeganHunter отличный ответ, я сделал это работает также для работы, после ES6 (что поддержка Прокси):
let NF = new Proxy(() => ({}), { get(target, name) { return NF } }); export function O<T>(someObject: T, defaultValue: T = NF as any as T) : T { if (typeof someObject === 'undefined' || someObject === null) return defaultValue; else return someObject; }и затем, возьмите typescript AST например,
var inf: InterfaceDeclaration = type.getSymbol().getDeclarations()[0] as InterfaceDeclaration;Это могут быть:
let inf: InterfaceDeclaration = O(O(O(type).getSymbol()).getDeclarations())[0] as InterfaceDeclaration;
в версии 2.9 поддерживает! https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#non-null-assertion-operator
const a = {} console.log(a!.b!.c)никаких дополнительных опций не требуется .tsconfig
Comments