JSDoc object methods with @method or @property?

djechlin picture djechlin · Apr 16, 2014 · Viewed 12.4k times · Source

JSDoc 3's documentation includes this example:

/**
 * The complete Triforce, or one or more components of the Triforce.
 * @typedef {Object} WishGranter~Triforce
 * @property {boolean} hasCourage - Indicates whether the Courage component is present.
 * @property {boolean} hasPower - Indicates whether the Power component is present.
 * @property {boolean} hasWisdom - Indicates whether the Wisdom component is present.
 */

/**
 * A class for granting wishes, powered by the Triforce.
 * @class
 * @param {...WishGranter~Triforce} triforce - One to three {@link WishGranter~Triforce} objects
 * containing all three components of the Triforce.
 */
function WishGranter() {}

I am essentially creating a class that takes an object that implements an interface MessageQueueConnector, which should have one method connectAndSubscribe implemented. Since Javascript does not distinguish between member functions and member variables, it makes sense to use property, and JSDoc's documentation implies that @method is unrelated. However, method sound a lot more correct so I'm wondering if this is preferred, or if I'm just doing all of this wrong anyway (i.e. if there is a simpler way to document this situation in the first place, without creating a type).

Answer

Louis picture Louis · Apr 16, 2014

@typedef is extremely limited in what it can do. You could define the methods as properties but then you would not be able to document parameters in the same way you would on a real class. What I've done to get around this limitation is to cheat. I use @class so that I can document it the way I want and put a warning that it is not a real class. So:

/**
 * @classdesc Not a real class but an interface. Etc...
 *
 * @name MessageQueueConnector
 * @class
 */

/**
 * This method does...
 *
 * @method
 * @name MessageQueueConnector#connectAndSubscribe
 * @param {string} whatever Whatever this is.
 * @returns {Object} Description of return value.
 * @throws {SomeException} blah.
 */

Note that the two doclets above do not need to have any associated JavaScript code. You don't need to create a fake class in JavaScript, you don't need to create a fake method, etc. This is why you need to use @name.

I don't like telling jsdoc that this is a class and then put in the doc that it is not but I found this to be the least objectionable way to get jsdoc to do what I want. I expect this workaround to become obsolete eventually as jsdoc evolves.