Как документировать возврат в JavaScript

Я пишу свою собственную библиотеку для проекта, работающего для приложения-браузера, и у меня возникает такая же старая проблема, когда вы решаете, как комментировать код.

Я пытаюсь следовать синтаксису JsDoc, но, вероятно, продолжит компилятор Google Closure способ. Я могу в конечном итоге использовать два тега @return и @returns в документации, просто для удобства переноса (когда я настраиваю автоматическое создание документации).

Теперь, вопрос, , как вы документируете возврат пользовательского анонимного объекта из функции? Например:

return {
    username: 'username',
    password: 'password',
    enabled:  true
};

JsDoc имеет пример того, как документ может быть документирован, чтобы ожидать объект с определенными полями, но не тег @returns. Аналогично, документация Google Closure Compiler для типа записи является неопределенной и не имеет примера для ее работы.

Ответ 1

Компилятор Closure использует подмножество аннотаций JSDoc (и добавляет несколько своих собственных). См. ссылка аннотации для компилятора для полной версии. Аннотации JSDoc аналогичны аннотации JavaDoc и представляют собой блок комментариев, который начинается с /** (две звезды). Хотя каждая строка комментария часто начинается с его собственного *, это соглашение, которое не требуется. В каждой строке разрешен только один тег JSDoc, но аргументы для тега могут охватывать несколько строк.

Аннотации обычно применяются к следующему выражению. Вот несколько примеров:

Переменные

/** @type {string} */ var a;

Тип Cast

var b = /** @type {string} */ (window['foo']);

обратите внимание на дополнительную скобку

Именованная функция

/**
 * @param {string} bar
 * @return {boolean}
 */
function foo(bar) { return true; }

Выражения функции

/** @type {function(string):boolean} */
var foo = function(bar) { return true; }

var foo2 =
  /**
   * @param {string} bar
   * @return {boolean}
   */
  function(bar) { return true; }

Typedef

Сложные типы (включая союзы и типы записей) могут быть сглажены для удобства и удобства использования с помощью typedef. Эти аннотации могут быть длинными, но могут быть разделены на несколько строк для удобства чтения.

/** @typedef {{
 *             foo:string,
 *             bar:number,
 *             foobar:number|string
 *           }}
 */
var mytype;

В вашем исходном примере существует несколько возможных способов аннотировать такое возвращаемое значение функции. Одним из наиболее специфических и по-прежнему удобным является тип записи:

/** @return {{username:string, password:string, enabled:boolean}} */
function() {
  return {
    username: 'username',
    password: 'password',
    enabled:  true
  }
}

Обратите внимание на дополнительный {}. Также имейте в виду, что типы записей не будут препятствовать переименованию свойств.

В этой аннотации компилятор сообщает, что функция возвращает анонимный тип с свойствами username, password и enabled. Другими допустимыми параметрами было бы определение интерфейса в другом месте, а тип - возвращаемое значение для этого интерфейса. Наименее специфическая аннотация была бы Object или *.

Чтобы увидеть широкий диапазон возможных аннотаций, посмотрите в extern файлы в проекте компилятора.

Ответ 2

Один из приятных и портативных способов сделать это выглядит следующим образом: использование return в качестве ключевого слова. https://github.com/senchalabs/jsduck/wiki/%40return

/**
 * @return {object} return An object with the following properties
 * @return {string} return.username Some username
 * @return {string} return.password Some password
 * @return {boolean} return.enabled Is the user enabled?
 */
function getObj () {
     return {
         username: 'username',
         password: 'password',
         enabled:  true
      };
}

Если вам нужно использовать его в нескольких местах, вам придется его дублировать или использовать @typedef, но я не понял, как добавлять комментарии к @typedef, поэтому я использую что-то вроде следующего

/**
 * @typedef {username:string, password:string, enabled:boolean} MyType
 *  
 *  username: The name of the user 
 *  password: Some password
 *  enabled: Is the user enabled?
 */

/**
 * @return {MyType}
 */
function getObj () {
     return {
         username: 'username',
         password: 'password',
         enabled:  true
      };
}

Вы также можете попробовать предложение здесь Как я могу документировать тип в webstorm, используя только jsdoc?

Ответ 3

Если положить это в начало функции

function myFunction() {
    /**
     * Description of my function
     * @return {!Object.<string, string|boolean>} Returns an object containing username, password and enabled information
     */

    // Do stuff
    return {
        username: 'username',
        password: 'password',
        enabled:  true
    }
}