Using JSDoc

Enhancing Javascript with JSDoc and JSDoc-checking IDEs

JSDoc is a way of documentating Javascript much like JavaDoc and Java annotations for Java. JSDoc does pretty much the same thing. It documents and annotates Javascript elements. However given that Javascript has much looser language rules than Java, these annotations can be leveraged to tighten parts of the code that may appear ambiguous particularly in a large project.

Probably the most useful features of JSDoc is the ability to sprinkle annotations amongst Javascript code which can then give semantic meaning to a function or variable. Using an advanced Javascript IDE, these annotations can be interpreted at compile time, and provide a kind of compile time checking, while also aiding in code-completion.

As of writing, the only IDE that can interpret JSDoc to any reasonable level is Webstorm. So all examples in this article are using the Webstorm IDE.

Simple Type Checking

Parameters types can be defined in the comments of the function. In this example we are annotating the x value being passed into the popup() method :

jsdoc_simple1a

Now we are passing in a number :

jsdoc_simple1b

Notice the squiggly line underneath the number 12345?

If we hover our mouse over the squiggly line, we should see a tooltip telling us what the problem is :

jsdoc_simple2

 

 

 

 

 

That’s pretty neat! Type checking at last! 

The @param JSDoc annotation allows us to say what we want passed into a function. We can also use this annotation on other primitive types such as number and boolean. Let’s have a look at how we can use the @param annotation on some more interesting objects.

 

Arrays and the Type Annotation

Javascript also has arrays and objects which can be considered types.

In the following example we are passing an array into a function :

jsdocx1

In the above we create two types of fruit, and make an array for each of them. By using angular brackets, we can define the type of the array being passed in (Array.<Apple> )

Using the @type annotation we can annotate a variable. In our array example we are stating that we want out element to be of type Banana. As the second array being passed in is of type Apple, our JSDoc annotation is being infringed and we get the squiggly gray line again.

At the time of writing Webstorm does not support the JSDoc checking of the inner type of an array when being passed to a function (See the comments).

Parameter annotations on arrays can also help in code completion.

jsdocx2

The JS compiler knows the element in an array is of type apple and shows the apple elements in the drop down list. This is unbelievably helpful!

Object Literals

Javascript objects can be very arbitrary objects. There is no real sense of type .

In the following example we are using the @param tag annotation again. Here we are annotating an object literal with two fields: name, and email which are both strings :

jsdoc_objlit1

 

 

 

 

 

 

In the method body, a variable is assigned to the user.name. This variable has to be of type string, and matches up with the name type being passed into the method.

The following two examples show where the IDE complains and the squiggly gray lines start appearing again :

jsdoc_objlit2

 

 

 

 

 

 

The @param annotation expects a number but we are passing in an array. Our @type annotation declares a variable to be string, but out @param says our user object can only be number.

In this case we are trying to treat one of the string fields as a number :

jsdoc_objlit3

 

 

 

 

 

 

 

We can even document an array of literals.

jsdoc_objlitarray1

 

 

 

 

 

 

 

 

 

In the following example the IDE will complain about the variable i being assigned to a string :

jsdoc_objlitarray2

 

 

 

 

 

 

 

 

 

 

Again, code completion is enhanced. The IDE deals with the fields in an object literal :

 

jsdoc_objlitarray3

 

 

Return Types

Returns can be annotated too.

In this example the IDE indicates there is a problem on the line where x is assigned the return value.

jsdoc_return1

 

 

 

 

 

 

In this example the assignment is correct, however there is now a problem with the return statement. The IDE picks up on what is happening inside the function is incorrect.

jsdoc_return2

 

 

 

 

 

Finally this example has everything working correctly :

jsdoc_return3

Mixed Type

Because Javascript is duck typed, methods can accepted objects of various types. Sometimes you want to document a function and tell it that it can only accept objects of these ‘types’.

jsdoc_mixedtype

 

 

 

 

 

 

 

 

 

 

The IDE will complain at exactly this line : processFruit(new Orange())

Wrapping up..

I hope this introduction to JSDoc was useful. I don’t believe in strictly enforcing JSDoc across a whole project, but I do feel that JSDoc with a JSDoc-checking IDE becomes necessary as the project grows bigger. It allows one to treat javascript functions as black boxes, and prevents lots of picking around inside a function to try and understand what is going wrong.

This is particularly useful when you have Javascript project modules, ie. Common projects that are used across other javascript projects. A typical real world implementation I have come across is a table component that is used across many projects. It has a setModel(..) method, where the table model is passed into the component (Just like in Swing J ). Using a JSDoc-checking IDE, the developer would be notified that this object being passed in requires an array of columns, an array of entities, and a method getValueAt among other things.


Posted in JavaScript, Tutorial | Tagged , , , | 5 Comments

5 Responses to Using JSDoc

  1. felixzacat says:

    test

  2. felixzacat says:

    test2

  3. felixzacat says:

    You have some pretty big inconsistencies in a few of your examples.

    For one, you should always use double curly braces when documenting an object param:

    /**
    * @param {{name:string, value:number}} nvPair
    */

  4. felixzacat says:

    In your examples you only do this when passing an array of objects, but if you think about it, every param tag uses curly braces to denote the type. If you just do this:

    /**
    * @param {name:string, value:number} nvPair
    */

    Then there’s actually nothing inside of the type declaration that tells the parser it’s an object.

    You also explain how to properly describe array parameters, and then you switch to another format with no explanation.

    // You go from this
    /** @type Array.SomeObjectType */

    // To this
    /** @type SomeObjectType[] */

  5. Kamalakannan says:

    Hi,
    Why param description is not shown in quick lookup in Webstorm. I tried both of the below format,

    With hyphen,
    @param {type} paramName – Param description

    Without hyphen,
    @param {type} paramName Param description

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

THREE_COLUMN_PAGE