Search code examples
javascriptecmascript-6webstormjsdoc

How to properly define own type of class in JSDoc?


I have a simple ES6 class and I'm wondering how to properly describe it in JSDoc. Note that I want to define my own type, which later would be recognized by WebStorm autocomplete.

Is below example valid?

/**
* @typedef {Object} View
* @class
*/
class View{...}

Solution

  • That's a really good question. The way I do today is to declare all my class instance variables in its constructor, annotating each one with its expected type. It's a good practice and works very well with Webstorm. For instance:

    class MyClass {
    
        constructor () {
            /** @type {Number} some number value */
            this.someNumber = 0;
            /** @type {String} some relevant string */
            this.someString = null;
            /** @type {Map<Number, Set<String>>} map numbers to sets of strings */
            this.strSetByNumber = new Map();
        }
    
        /**
         * Some sample function.
         * 
         * @param {Number} a - first value
         * @param {Number} b - second value
         * @return {Number} the resulting operation
         */
         someFunction(a, b) {
             return a + b;
         }
    }
    

    Now just declare some variable as being of type MyClass and enjoy auto-completion:

    auto-completion

    And if you try to assign a wrong type to some of your properties:

    enter image description here


    Sometimes, however, you don't even need to declare a class. Say, for isntance, you expect to receive an object via JSON and you need to something with it. You can use pure JSDoc to help checking your code, with no need for declaring a class. Say you're expecting a JSON like this:

    {
        "foo": "bar",
        "fizz": 42
    }
    

    Instead of declaring a class, do this instead at some place in your code (I prefer putting it always at the top of the script that is going to make use of it):

    /**
     * @typedef {Object} MyType
     * @property {String} foo - this is some cool string
     * @property {Number} fizz - some number we also expect to receive
     * @property {Number} [bar] - an optional property
     */
    

    And that's it! Try it for yourself and see how Webstorm is able to understand both approaches just fine.