Search code examples
javascriptnode.jsdocumentationwebstormjsdoc

JSDoc - type definition with partial creation


We are using Webstorm and JSDoc for some nice suggestion functionality and for type documentation when needed.

For example, this is definition of User, which is used multiple times across the app.

/**
     * Basic user object
     * @typedef {Object} User
     * @property {!Number} id - Unique identitifaction
     * @property {!String} email - Email and username in once
     * @property {!Boolean} enabled - True, if user can access the system
     * @property {!Boolean} confirmed - True, if validation (i.e. through email) was successfull
     *
     * @property {?String} name - Name of user
     */

Then we can use him for example in service method for selecting by some detail of user

/**
 * return Detail of user
 * @param {User} params
 * @param {Options=} options
 * @returns Promise.<User>
 */
exports.userDetail = (params, options = {}) => {
    return userRepository.userDetail(params, options);
};

By far it works really great, when I use params in exports.userDetail method, it autosuggest us the fields we can use if we want.

The problem is "on the top of tree". For example standard CRUD operation for detail is using this method and selecting only by id

/**
 * @param {Number} req.userId
 */
exports.detail = (req, res, next) => {
    return userService.userDetail({id: req.userId}).then(user => {
        res.out = user;
        return next();
    }).catch(next);
};

However at this part {id: req.userId} webstorm calls an error: 'Argument type ... is not assignable to parameter type User'

The only solution is to name ALL the properties otherwise it says this. For other cases this warning is really helpful - it finds out, if you put Number into string or like Token into User by mistake etc. However mixing the real errors with this one makes it less reliable.

Anyone is having some tips for JSDoc or Webstorm in general? I didnt find a way how to say "This parametr is user even without all the fields, not all of them are mandatory".

On the other hand, I want to share ONE model across the application - I can write complete definition at each function, which is working correctly

/**
 * Register standard user
 * @param {String} _params.email Unique email for registration, used also instead of username
 * @param {String} _params.password Password for your account
 * @param {Options=} options
 */

But when we are using User in a lot o methods, every change would mean A LOT work to update it in the whole application (almost impossible when it grows big enough)


Solution

  • You can try defining your properties as optional - like

    /**
         * Basic user object
         * @typedef {Object} User
         * @property {!Number} id - Unique identitifaction
         * @property {!String} [email] - Email and username in once
         * @property {!Boolean} [enabled] - True, if user can access the system
         * @property {!Boolean} [confirmed] - True, if validation (i.e. through email) was successfull
         *
         * @property {?String} name - Name of user
         */