Позвольте мне сначала сказать сходство между методом, украшенным с помощью метода @classmethod vs @staticmethod.
Сходство: оба они могут быть вызваны самим классом Class , а не только экземпляр класса. Таким образом, оба они в некотором смысле являются методами класса .
Разница: класс-метод получит сам класс как первый аргумент, в то время как staticmethod не делает.
Таким образом, статический метод, в некотором смысле, не связан с самим классом и просто висит там только потому, что может иметь связанную функциональность.
>>> class Klaus:
@classmethod
def classmthd(*args):
return args
@staticmethod
def staticmthd(*args):
return args
# 1. Call classmethod without any arg
>>> Klaus.classmthd()
(__main__.Klaus,) # the class gets passed as the first argument
# 2. Call classmethod with 1 arg
>>> Klaus.classmthd('chumma')
(__main__.Klaus, 'chumma')
# 3. Call staticmethod without any arg
>>> Klaus.staticmthd()
()
# 4. Call staticmethod with 1 arg
>>> Klaus.staticmthd('chumma')
('chumma',)
Я не могу найти никакой ссылки на него в спецификации языка для языка программирования .
Что касается вызова этого оператора в CoffeeScript, он называется экзистенциальным оператором ( в частности, «вариант доступа» экзистенциального оператора.
Из Документация CoffeeScript по операторам :
Вариант доступа для экзистенциального оператора
blockquote>?.
может использоваться для впитывания нулевых ссылок в цепочке свойств. Используйте его вместо доступа к точкам.
в случаях, когда базовое значение может быть нулевым или неопределенным.Таким образом, вариант доступа экзистенциального оператора, как представляется, является правильным способом ссылки к этому оператору; и TypeScript в настоящее время не поддерживает его (хотя другие выразили желание использовать эту функциональность ).
Не так хорошо, как сингл?, но он работает:
var thing = foo && foo.bar || null;
Вы можете использовать как можно больше & amp; & amp; как вам нравится:
var thing = foo && foo.bar && foo.bar.check && foo.bar.check.x || null;
На github есть открытый запрос функции, где вы можете озвучить свое мнение / желание: https://github.com/Microsoft/TypeScript/issues/16
Как уже было сказано, в настоящее время все еще рассматривается, но уже несколько лет мертв в воде .
Основываясь на существующих ответах, вот наиболее краткое руководство версия Я могу думать:
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'));
Изменить: я обновил ответ благодаря комментарию 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
}
Мы создали этот метод util при работе над Phonetradr , который может дать вам безопасный доступ к глубоким свойствам с помощью TypScript:
/**
* 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);
Это определено в спецификации 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<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'));
Оператор ?.
не поддерживается в 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
plus, вы можете установить значение по умолчанию:
o(o(o(o(test).prop1).prop2, "none")
Он отлично работает с IntelliSense в Visual Studio.
В версии 2.9 поддерживается! https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#non-null-assertion-operator
const a = {}
console.log(a!.b!.c)
no any дополнительные параметры, необходимые в .tsconfig