JSDoc: Return object structure
Asked Answered
G

3

254

How can I tell JSDoc about the structure of an object that is returned. I have found the @return {{field1: type, field2: type, ...}} description syntax and tried it:

/**
 * Returns a coordinate from a given mouse or touch event
 * @param  {TouchEvent|MouseEvent|jQuery.Event} e    
 *         A valid mouse or touch event or a jQuery event wrapping such an
 *         event. 
 * @param  {string} [type="page"]
 *         A string representing the type of location that should be
 *         returned. Can be either "page", "client" or "screen".
 * @return {{x: Number, y: Number}} 
 *         The location of the event
 */
var getEventLocation = function(e, type) {
    ...

    return {x: xLocation, y: yLocation};
}

While this parses successfully, the resulting documentation simply states:

Returns: 
    The location of an event
    Type: Object

I am developing an API and need people to know about the object that they will get returned. Is this possible in JSDoc? I am using JSDoc3.3.0-beta1.

Gossipry answered 27/2, 2015 at 10:49 Comment(1)
I know that @typedef is a workaround/solution, but it seems weird for this to not work with literal objects. If anyone stumbles upon this in the future (as I did) I've added an issue github.com/jsdoc/jsdoc/issues/1678 that could have more info than this page.Framing
G
422

Define your structure separately using a @typedef:

/**
 * @typedef {Object} Point
 * @property {number} x - The X Coordinate
 * @property {number} y - The Y Coordinate
 */

And use it as the return type:

/**
 * Returns a coordinate from a given mouse or touch event
 * @param  {TouchEvent|MouseEvent|jQuery.Event} e    
 *         A valid mouse or touch event or a jQuery event wrapping such an
 *         event. 
 * @param  {string} [type="page"]
 *         A string representing the type of location that should be
 *         returned. Can be either "page", "client" or "screen".
 * @return {Point} 
 *         The location of the event
 */
var getEventLocation = function(e, type) {
    ...

    return {x: xLocation, y: yLocation};
}
Gardel answered 27/2, 2015 at 11:6 Comment(7)
Thanks. Multiple @return statements do indeed work, but they are listed in the output as if they were several returns (One bullet point states point - Object and then two other bullet points for point.x - Number and point.y - Number). While I can live with that, I suppose there is no way of having a condensed output of the returned object? Or at the very least have the entries for point.x and point.y indented?Gossipry
Yes, that does seem like the best option. I thought there might be a way to have a non-named return entity, but the @typedef approach is the most clear one in terms of documentation output, thanks!Gossipry
groovy, removed the first option as 2nd option is simply best.Gardel
You better add @inner or type definition will have global scope in the documentation. +1Hereford
I've always used @typedef {Object} Point. In fact, using this two-line form highlights Point in PhpStorm with the message "Unresolved variable or type Point". The @typedef docs support this, but I don't want to edit this answer if it's a valid variant.Blouin
@DavidHarkness Yes, explicitly defining {Object} before the type name seems to be the correct way to do it.Compensation
Lovely to see this is supported in Google App Script as well.Manufactory
O
49

An alternative to the suggestions already posted, you can use this format:

/**
 * Get the connection state.
 *
 * @returns {Object} connection The connection state.
 * @returns {boolean} connection.isConnected Whether the authenticated user is currently connected.
 * @returns {boolean} connection.isPending Whether the authenticated user's connection is currently pending.
 * @returns {Object} connection.error The error object if an error occurred.
 * @returns {string} connection.error.message The error message.
 * @returns {string} connection.error.stack The stack trace of the error.
 */
getConnection () {
  return {
    isConnected: true,
    isPending: false,
    error
  }
}

which will give the following documentation output:

    Get the connection state.

    getConnection(): Object

    Returns
    Object: connection The connection state.
    boolean: connection.isConnected Whether the authenticated user is currently connected.
    boolean: connection.isPending Whether the authenticated users connection is currently pending.
    Object: connection.error The error object if an error occurred.
    string: connection.error.message The error message.
    string: connection.error.stack The stack trace of the error.
Oreopithecus answered 29/5, 2019 at 18:17 Comment(1)
this leads to "method returns Object OR String OR Boolean" - every @returns adds a new return-option, instead of descriptions for fields of the returned object.Imena
G
22

A clean solution is to write a class and return that.

/** 
 *  @class Point
 *  @type {Object}
 *  @property {number} x The X-coordinate.
 *  @property {number} y The Y-coordinate.
 */
function Point(x, y) {
  return {
        x: x,
        y: y
    };
}

/**
 * @returns {Point} The location of the event.
 */
var getEventLocation = function(e, type) {
    ...
    return new Point(x, y);
};
Gulgee answered 21/4, 2016 at 4:26 Comment(5)
When I do this but use the Google Closure Compiler, I get a warning: "cannot instantiate non-constructor". I tried adding @constructor to the function (above the @return) but it didn't help. If someone knows how to fix that, please let me know. Thanks!Arras
@AndroidDev this is because the function Point is not a constructor, to change that replace the body of the Point function with this.x = x; this.y = y;Elwira
I don't see the reason why we need to use new here, why not just return Point(x, y)?Formwork
@CHANist, new syntax is to create an instance from the constructor. Without new, the context of this would be the global context. You can try creating an instance without new to see the effect.Constantia
You forgot to describe the @returns on your Point JSDocs.Minh

© 2022 - 2024 — McMap. All rights reserved.