Аннотации компилятора закрытия Google для передачи перечислений

Кажется, я не могу найти правильные аннотации компилятора закрытия, чтобы передать карту перечислений.

Например: заданы EventTargets A, B с:

/** @enum {string} */
MYNS.A.EventType = {EA : 'ea1'};

/** @enum {string} */
MYNS.B.EventType = {EB : 'eb2'};

У меня есть конструктор C, который возвращает несколько типов событий:

/** @return {WHATSTHIS} */
C.prototype.getEventTypesAB = function() {
  return {
    A: MYNS.A.EventType,
    B: MYNS.B.EventType
  };
};

для использования позже:

goog.events.listen(parent, c.getEventTypesAB().A.EA, ...);

Я пробовал несколько вещей, таких как ниже, которые, я думаю, не работают, поскольку enum не является type, но у меня нет идей, как это аннотировать:

/** @typedef {{ A: MYNS.A.EventType, B: ... }} */

Я всегда получаю (ожидаемое) предупреждение компилятора: WARNING - Property EA never defined on String на клиенте.


person bebbi    schedule 17.06.2016    source источник


Ответы (2)


MYNS.A.EventType — это объект, ключи которого являются строками, а значения являются членами этого перечисления. Таким образом, вы могли бы написать

/** @type {!Object<string, MYNS.A.EventType>} */ var obj = MYNS.A.EventType

и это будет typecheck. Аналогично для B. Таким образом, тип литерала объекта, который вы возвращаете, является типом записи, {A: !Object<string, MYNS.A.EventType>, B: !Object<string, MYNS.B.EventType>}

person MatrixFrog    schedule 17.06.2016
comment
да, разница между экземпляром типа и типом объекта, определяющего тип, иногда сбивает с толку. - person John; 19.06.2016

Этот код компилируется с помощью онлайн-сервис компилятора закрытия:

goog.provide("MYNS.A.EventType");
goog.provide("MYNS.B.EventType");
goog.provide("MYNS.C.ComboType");
goog.provide("MYNS.C");
/** @enum {string} */
MYNS.A.EventType = {EA : 'ea1'};
/** @enum {string} */
MYNS.B.EventType = {EB : 'eb2'};
/** @typedef {{ A: MYNS.A.EventType, B: MYNS.B.EventType }} */
MYNS.C.ComboType;
MYNS.C = function() {};
/** @return {!MYNS.C.ComboType} */
C.prototype.getEventTypesAB = function() {
  return {
    A: MYNS.A.EventType,
    B: MYNS.B.EventType
  };
};
var foo = new C();
var r = foo.getEventTypesAB();
console.log(r.A.EA);
console.log(r.B.EB);

Я не пробовал запускать получившийся просто скомпилированный код, но, похоже, он должен работать. Вот что дает компилятор с простой компиляцией и красивой печатью:

var MYNS = {A:{}, B:{}};
MYNS.A.EventType = {EA:"ea1"};
MYNS.B.EventType = {EB:"eb2"};
MYNS.C = function() {
};
C.prototype.getEventTypesAB = function() {
  return {A:MYNS.A.EventType, B:MYNS.B.EventType};
};
var foo = new C, r = foo.getEventTypesAB();
console.log(r.A.EA);
console.log(r.B.EB);

Я думаю, что вам не хватает шага, чтобы определить тип с именем пространства имен, как в этих строках:

/** @typedef {{ A: MYNS.A.EventType, B: MYNS.B.EventType }} */
MYNS.C.ComboType;

Это то, что показано на этой странице, которую я считаю наиболее полезной страницей о синтаксисе Google Closure:

https://developers.google.com/closure/compiler/docs/js-for-compiler#tags

person owler    schedule 17.06.2016