skip to Main Content

I was coding some JavaScript modules trying to have the intellisense working on VsCode with the JsDocs

But now I’m struggling trying to write the JsDoc for the following case:

Suppose I have this classes

class SomeClass extends Array {}
class SomeOtherClass extends String {}

And I want to create this function to extend them

function WithFeature(base) {
  return class extends base {
    constructor() {
      super(...arguments)
    }
    feature(){
      // do something...
    }
  }
}

So I can make more cool classes

class CoolClass extends WithFeature(SomeClass) {
  // ...
}

class OtherCoolClass extends WithFeature(SomeOtherClass) {
  // ...
}

How can I JsDoc my beatifull WithFeature?

I thought something like this would work

/**
 * @template {T}
 * @param {new () => T} base 
 * @returns {new () => T}
 */
function WithFeature(base) {
  // ...
}

or maybe this

/** @type {<T>(base: T) => new () => T} */
function WithFeature(base) {
// ...

But of course it didn’t work for me (ie. it didn’t show the intellisense hints on VsCode) otherwise I wouldn’t asked this question!

Have somebody else encountered the same drama?


Edit

I noticed this that can be a step toward the solution!

class SomeClass extends Array {}
class SomeOtherClass extends String {}

/**
 * @template T
 * @returns {T}
 */
function WithFeature(/** @type {T} */ base) {
  return class extends base {
    feature(){
      // do something...
    }
  }
}

class CoolClass extends WithFeature(SomeClass) {
  // I can press ctrl-space to see the properties and methods
  // from the SomeClass (and from Array) but not from WithFeature
}

class OtherCoolClass extends WithFeature(SomeOtherClass) {
  // I can press ctrl-space to see the properties and methods
  // from the SomeOtherClass (and from String) but not from WithFeature
}

But still I couldn’t find a way to see the hints of WithFeature (ie. the feature()=>void method)

I also tried /** @returns {{feature()=>void} & T} */ but still VsCode is showing me only the properties from the T type but not the new feature method from WithFeature

2

Answers


  1. Chosen as BEST ANSWER

    I think I can post an answer for my own question!

    The key point is that because the argument of WithFeature is a constructor itself and the type T that I want to grasp is the type of the instance of such constructor, I need to pick the @template T from the /** @type {new()=>T} */ of the base argument so that the method can @returns a constructor of type new () => (T & SomeOtherType).

    But this solution still is has some flaws...

    class SomeClass extends Array {}
    class SomeOtherClass extends String {}
    
    /**
     * @typedef {{feature()=>void}} WithFeatureType
     */
    
    /**
     * @template T
     * @returns {new () => (T & WithFeatureType)}
     */
    function WithFeature(/** @type {new()=>T} */ base) {
      return class extends base {
        feature(){
          // do something...
        }
      }
    }
    
    class CoolClass extends WithFeature(SomeClass) {
      // now pressing ctrl-space will show all the properties and methods
      // from SomeClass, from Array and from from WithFeatureType
    }
    
    // Anyway is not perfect because
    class OtherCoolClass extends WithFeature(SomeOtherClass) {
       constructor() {
          // passing the mouse over the 'super' keyword should show
          // the arguments of the parent constructor but with this
          // solution they are lost
          super()
       }
    }
    

    To conclude, if you do

    /**
     * @template T
     * @returns {T}
     */
    function WithFeature(/** @type {T} */ base) {
    

    Then the IDE can show everything but the stuff added by WithFeatureType (so the feature method is not shown).

    Otherwise with

    /**
     * @typedef {{feature()=>void}} WithFeatureType
     */
    
    /**
     * @template T
     * @returns {new () => (T & WithFeatureType)}
     */
    function WithFeature(/** @type {new()=>T} */ base) {
    

    You can see both the stuff from T and from WithFeatureType but you lose the info about the arguments of the base constructor.

    Further investigations are needed!


  2. you can use this format:

        **
         * WithFeature 
         * @param {class} base base class
         * @returns {class} new class that extends base
         */
        function WithFeature(base) {
          return class extends base {
            constructor() {
              super(...arguments);
            }
            feature() {
              // do something...
            }
          };
        }
    

    For class:

    /**
     * Someclass
     * @class
     */
    class Someclass extends Array{
      someFun(){
        return "I am someclass property"
      }
    }
    
    class test extends Someclass{
      /** When you press click + space it shows someFun + Array properties*/
    }
    

    Reason for doesn’t showing

    class CoolClass extends WithFeature(Someclass) {
      // Because WithFeature is a function, it only return the extended class in run time
      //obviously the IDE intelligence don't run the function while you are typing
    }
    

    I suggest you to directly use the above method

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search