Search code examples
javascriptvisual-studio-codeintellisensejsdoc

JSdoc vscode intellisense on monkey patched / added function?


Here's an example of what I'm trying to do.

Just wondering if there's any way to accomplish having the moo method referenced in other places on VS code populate intellisense using jsdoc. Right now it just shows any.

lib/newmoment.js

/**
 * @module lib/newmoment
 */
const moment = require('moment');

/**
 * do the moo
 * @returns {String} moo
 */
moment.moo = function(){
  return 'moo'
}

module.exports = moment;

test.js which uses lib/newmoment.js

const moment_modified = require('./lib/newmoment')

console.log(moment_modified.moo());

Screenshots showing any, however I'm trying to get the intellisense to show do the moo:

referenced function

original function


Update...

I found a way to sort of hack in what I was looking for without an intersection type using JSdoc (your mileage may vary). Screenshots with results below. It is not the cleanest for sure, but may at least get you by until you have the chance to refactor code (see @adsy suggestions)

updated lib/newmoment.js

/**
 * @namespace NewMoment
 */
const NewMoment = {
  /**
    * do the moo
    * @returns {String} moo
  */
  moo(){}
}

/**
 * @type {NewMoment}
 */
const moment = require('moment');

moment.moo = function(){
  return 'moo'
}

module.exports = moment;

test.js remains the same as before

in test.js, shows jsdoc

in lib/newmoment.js, shows jsdoc


Solution

  • The easiest way would be to use an intersection type (&) between the original type and the new type. Object.assign already implies this, and also requires an object literal to be passed for that "new type".

    In turn, object literals are easy to markup with further JSDoc.

    /**
     * @module lib/newmoment
     */
    
    const moment = require('moment');
    
    module.exports = Object.assign(moment, {
        /**
         * do the moo
         * @returns {String} moo
         */
        moo() {
            return 'moo';
        }
    });
    

    Note both this and your original example actually mutate the original module, which is not great practice. You may wish to use Object.assign({}, moment, { // ...etc.