Як вказати роздільну здатність та тип відхилення обіцянки в JSDoc?


83

У мене є код, який повертає об'єкт обіцянки, наприклад, використання бібліотеки Q для NodeJS.

var Q = require('q');

/**
 * @returns ???
 */
function task(err) {
    return err? Q.reject(new Error('Some error')) : Q.resolve('Some result');
}

Як задокументувати таке повернене значення за допомогою JSDoc?


Мені цікаво було щось подібне. Як задокументувати тип повернення функції, яка може повертати кілька різних речей на основі введення та стану програми?
Гофман

Використовуйте синтаксис підстановки : @returns {*}
Paul Sweatte,

Синтаксис узагальнюючих знаків не такий конкретний і не допомагає.
Арікон

2
@arikon Чи @returns {ErrorObject|ResultObject}допомагає? Використання знака "труба" в описі типу - звичайна практика.
John Doe

3
@ john-doe Ні, це не так. Оскільки функція повертає об’єкт Promise, а не просто результат чи помилку.
Arikon

Відповіді:


72

Навіть якщо вони не існують у Javascript, я виявив, що JSdoc розуміє "загальні типи".

Таким чином, ви можете визначити власні типи, а потім використовувати /* @return Promise<MyType> */. Наступний результат дає приємний TokenConsume (маркер) → {Promise. <Token>} із посиланням на ваш власний Tokenтип у документі.

/**
 * @typedef Token
 * @property {bool} valid True if the token is valid.
 * @property {string} id The user id bound to the token.
 */

/**
 * Consume a token
 * @param  {string} token [description]
 * @return {Promise<Token>} A promise to the token.
 */
TokenConsume = function (string) {
  // bla bla
}

Він навіть працює з /* @return Promise<MyType|Error> */або /* @return Promise<MyType, Error> */.


1
@Sebastian так, це ідея!
jillro

Для YUIDoc я знайшов це:@return {Promise|Token}
J Chris

хороша ідея! я змінив його на:@returns {Promise<ForumPost>|Promise<false>|Error}
Przemek Lewandowski

1
Мені дуже не подобається це рішення, оскільки jsdoc відокремлює typedef на іншій сторінці, ніж функція, яка повертає його. Це також вимагає від вас назвати всі ваші типи об’єктів, що дозволяють вирішити, але все, що ви дійсно хочете зробити, це повернути декілька значень і обернути їх в об’єкт.
Боб МакЕлрат

2
Оновлення від власника проекту щодо поточного рішення та того, що планується до випуску github.com/jsdoc3/jsdoc/issues/1197#issuecomment-312948746
Mike Grace,

7

Я схильний визначати зовнішній тип для обіцянки:

/**
* A promise object provided by the q promise library.
* @external Promise
* @see {@link https://github.com/kriskowal/q/wiki/API-Reference}
*/

Тепер ви можете описати у @returnвиписці документації до своєї функції, що відбувається з обіцянкою:

/**
* @return {external:Promise}  On success the promise will be resolved with 
* "some result".<br>
* On error the promise will be rejected with an {@link Error}.
*/
function task(err) {
    return err? Q.reject(new Error('Some error')) : Q.resolve('Some result');
}

6

За допомогою JSDoc ви також можете створювати власні типи за допомогою @typedef. Я використовую це зовсім небагато, тому реквізити / параметри, які є рядками або масивами, посилаються на опис типу (наприклад, для stringя створив typedef, що включає власні елементи, доступні для рядка (див. Приклад JSDoc нижче). Ви можете визначити власний тип тим самим чином. Це тому, що ви не можете використовувати позначення точки об’єкта для повернень, як це можна для @property для позначення того, що є у поверненні. Отже, у випадках, коли ви повертаєте щось на зразок об’єкта, ви можете створити визначення для цього типу (' @typedef MyObject), а потім @returns {myObject} Definition of myObject.

Однак я б не збожеволів від цього, оскільки типи повинні бути максимально буквальними, і ви не хочете забруднювати свої типи, але бувають випадки, коли ви хочете чітко визначити тип, і ви можете задокументувати, що таке в ньому (хороший приклад - Modernizr ... він повертає об'єкт, але у вас немає документації до нього, тому створіть власний typedef, який деталізує, що є у цьому поверненні).

Якщо вам не потрібно їхати цим шляхом, тоді, як хтось уже згадав, ви можете вказати кілька типів для будь-якого @param, @property або @return, використовуючи конвеєр |.

У вашому випадку, ви повинні також документувати , @throwsтому що ви кидаєте new error: * @throws {error} Throws a true new error event when the property err is undefined or not available.

//saved in a file named typedefs.jsdoc, that is in your jsdoc crawl path
/**
    * @typedef string
    * @author me
    * @description A string literal takes form in a sequence of any valid characters. The `string` type is not the same as `string object`.
    * @property {number} length The length of the string
    * @property {number} indexOf The occurence (number of characters in from the start of the string) where a specifc character occurs
    * @property {number} lastIndexOf The last occurence (number of characters in from the end of the string) where a specifc character occurs
    * @property {string|number} charAt Gives the character that occurs in a specific part of the string
    * @property {array} split Allows a string to be split on characters, such as `myString.split(' ')` will split the string into an array on blank spaces
    * @property {string} toLowerCase Transfer a string to be all lower case
    * @property {string} toUpperCase Transfer a string to be all upper case
    * @property {string} substring Used to take a part of a string from a given range, such as `myString.substring(0,5)` will return the first 6 characters
    * @property {string} substr Simialr to `substring`, `substr` uses a starting point, and then the number of characters to continue the range. `mystring.substr(2,8)` will return the characters starting at character 2 and conitnuing on for 8 more characters
    * @example var myString = 'this is my string, there are many like it but this one is HOT!';
    * @example
    //This example uses the string object to create a string...this is almost never needed
    myString = new String('my string');
    myEasierString = 'my string';//exactly the same as what the line above is doing
*/

1
На жаль, це не працює в PHPStorm, який виділяє тип у @typedefтегу як невирішений. Так, так, я визначаю це тут!
David Harkness

Я не кидаю помилку, просто створюю її екземпляр, щоб передати її Q.reject ()
Arikon

6

Синтаксис, який зараз підтримує Jsdoc3:

/**
 * Retrieve the user's favorite color.
 *
 * @returns {Promise<string>} A promise that contains the user's favorite color
 * when fulfilled.
 */
User.prototype.getFavoriteColor = function() {
     // ...
};

Підтримувати в майбутньому?

/**
 * A promise for the user's favorite color.
 *
 * @promise FavoriteColorPromise
 * @fulfill {string} The user's favorite color.
 * @reject {TypeError} The user's favorite color is an invalid type.
 * @reject {MissingColorError} The user has not specified a favorite color.
 */

/**
 * Retrieve the user's favorite color.
 *
 * @returns {FavoriteColorPromise} A promise for the user's favorite color.
 */
User.prototype.getFavoriteColor = function() {
    // ...
};

Див. Обговорення github за адресою: https://github.com/jsdoc3/jsdoc/issues/1197


1
Щойно знайшов те саме. Посилання на коментар, на яке посилається вище власник проекту github.com/jsdoc3/jsdoc/issues/1197#issuecomment-312948746
Mike Grace

4

Існує також інший спосіб зробити це, хоча це може бути ЗАСТОСОВАНО . Упор на міць , так як хто - то говорить , що це засуджується (перевірте коментарі до цієї відповіді) в той час як інші говорять , або один добре. Я все одно повідомляю про це заради повноти.

Тепер візьмемо, Promise.all()наприклад, який повертає Promise, виконане з масивом. Зі стилем точкових позначень це буде виглядати, як показано нижче:

{Promise.<Array.<*>>}

Він працює на продуктах JetBrains (наприклад, PhpStorm, WebStorm), а також використовується в документах jsforce .

На момент написання статті, коли я намагаюся автоматично згенерувати деякі документи за допомогою PHPStorm, він за замовчуванням застосовує цей стиль, навіть незважаючи на те, що я посилався на нього погано.

У будь-якому випадку, якщо взяти наступну функцію як приклад:

// NOTE: async functions always return a Promise
const test = async () => { 
    let array1 = [], array2 = [];

    return {array1, array2};
};

Коли я дозволяю PhpStorm створювати документи, я отримую це:

/**
 * @returns {Promise.<{array1: Array, array2: Array}>}
 */
const test = async () => {
    let array1 = [], array2 = [];

    return {array1, array2};
};

0

Ось те, що я люблю робити (з яким можна трохи переборщити):

/**
 * @external Promise
 * @see {@link http://api.jquery.com/Types/#Promise Promise}
 */

/**
 * This callback is called when the result is loaded.
 *
 * @callback SuccessCallback
 * @param {string} result - The result is loaded.
 */

/**
 * This callback is called when the result fails to load.
 *
 * @callback ErrorCallback
 * @param {Error} error - The error that occurred while loading the result.
 */

/**
 * Resolves with a {@link SuccessCallback}, fails with a {@link ErrorCallback}
 *
 * @typedef {external:Promise} LoadResultPromise
 */

/**
 * Loads the result
 *
 * @returns {LoadResultPromise} The promise that the result will load.
 */
function loadResult() {
    // do something
    return promise;
}

В основному, визначте базову обіцянку із посиланням на якусь документацію (у цьому випадку я посилаюся на jQuery), визначте свої зворотні виклики, які будуть викликані, коли обіцянка або вирішується, або не вдається, потім визначте свою конкретну обіцянку, яка посилається назад на документація зворотного дзвінка.

Нарешті, використовуйте свій конкретний тип обіцянки як тип повернення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.