Document destructured function parameter in JSDoc

26,430

Solution 1

This is how it's intended, as described in the documentation.

/**
 * My cool function.
 *
 * @param {Object} obj - An object.
 * @param {string} obj.prop1 - Property 1.
 * @param {string} obj.prop2 - Property 2.
 */
const fn = function ({prop1, prop2}) {
  // Do something with prop1 and prop2
}

So, your first example is pretty much correct.

Another example with some deeper nesting:

/**
 * Nesting example.
 *
 * @param {object} param
 * @param {number} param.a - First value
 * @param {object} param.b - Wrapper
 * @param {number} param.b.c - Second value
 * @return {number} sum a and b
 */
const letters = ({a, b: {c}}) => a + c;

Solution 2

I personally use this one:

/**
* @param {{
  a: number
  b: number
}} param0
* @returns {number} The sum
*/
const func = ({ a, b }) => a + b;

Just create the object right there.

I also take advantage of TypeScript, and would declare obtional b as b? or b: number | undefined as JSDoc also allows unions

Share:
26,430

Related videos on Youtube

morkro
Author by

morkro

Hello there! I'm a Software Engineering Director at McKinsey & Company. I focus on delivering high performing web applications, building engineering teams, and supporting companies to create successful digital businesses.

Updated on July 08, 2022

Comments

  • morkro
    morkro almost 2 years

    Previously I've always documented my object parameters as follows:

    /**
     * Description of the function
     *
     * @param {Object} config - The configuration
     * @param {String} config.foo
     * @param {Boolean} [config.bar] - Optional value
     * @return {String}
     */
    function doSomething (config = {}) {
      const { foo, bar } = config;
      console.log(foo, bar);
      // do something
    }
    

    But I am unsure what the best approach is with desctructured function parameter. Do I just ignore the object, define it somehow or what is the best way of documenting it?

    /**
     * Description of the function
     *
     * @param {String} foo
     * @param {Boolean} [bar] - Optional value
     * @return {String}
     */
    function doSomething ({ foo, bar } = {}) {
      console.log(foo, bar);
      // do something
    }
    

    I feel like my approach above doesn't make it obvious that the function expects an object and not two different parameter.

    Another way I could think of would be using @typedef, but that might end up being a huge mess (especially in a larger file with many methods)?

    /**
     * @typedef {Object} doSomethingConfiguration
     * @property {String} foo
     * @property {Boolean} [bar] - Optional value
     */
    
    /**
     * Description of the function
     *
     * @param {doSomethingConfiguration}
     * @return {String}
     */
    function doSomething ({ foo, bar } = {}) {
      console.log(foo, bar);
      // do something
    }
    
    • Bergi
      Bergi about 8 years
      I think the first approach is still fine. Nobody cares whether the object is named config in your code or does have any name at all.
    • Mörre
      Mörre about 8 years
      In WebStorm I have found that if I just describe the (after-destructuring) parameters and ignore the destructuring it mostly works except for less-common cases. So in your example, describe two parameters foo and bar. It's not a final solution, but any approach using an object yielded inspection errors - and inspections and autocompletions from the IDE is what I care about most.
  • Bergi
    Bergi about 8 years
    Isn't he already doing that? He is asking what to do now that there is no employee variable in the function any more.
  • Mörre
    Mörre about 8 years
    This doesn't answer the question - this example does not use destructuring! With destructuring you have no parent object.
  • ZachB
    ZachB about 6 years
    I don't see how JSDoc unambiguously works when you have multiple destructured arguments, like function ({a}, {a}) {}. The JSDoc I guess would be @param {object} param1, @param {*} param1.a, @param {object} param2, @param {*} param2.a, and rely on ordering of the @param tags?
  • Cerbrus
    Cerbrus about 6 years
    @ZachB: function ({a}, {a}) {} is invalid syntax, since a is defined twice, there.
  • ZachB
    ZachB about 6 years
    Oops. ({a: b}, {a})) or ({a}, {b}) -- point was that JSDoc @param tags are orderless AFAIK and the keys can be ambiguous were JSDoc to try to match using property names. The next version of VSCode is going to use positional lookup to resolve this scenario.
  • notacouch
    notacouch over 5 years
    Actually his same link, right after his example gives a relative example with the same exact jsdoc comments for Project.prototype.assign = function({ name, department }). Prior to the example they say, "If a parameter is destructured without an explicit name, you can give the object an appropriate one and document its properties."
  • Cerbrus
    Cerbrus almost 5 years
    Thanks, @d0gb3r7. I've updated the link in the answer.
  • Jean Paul
    Jean Paul about 3 years
    With this I get the eslint warning: "Missing JSDoc parameter description for 'param'." (valid-jsdoc)
  • Cerbrus
    Cerbrus about 3 years
    @JeanPaul: then you need to add a description
  • connexo
    connexo about 3 years
    I'm getting The type of a function declaration must match the function's signature. from VS Code ts engine with that.
  • Damien Golding
    Damien Golding over 2 years
    For multiple parameters, just add the name(no type will use whatever is detected). const letters = (d, {a, b: {c}}) => a + c; Add [at]param {number} d Or [at]param d to not override type.
  • Damien Golding
    Damien Golding over 2 years
    For multiple parameters, just add the name(no type will use whatever is detected). const letters = (d, {a, b: {c}}) => a + c; Add [at]param {number} d Or [at]param d to not override type.