Validating JavaScript Code with JSDoc Types Annotations

Konstantin Ulitin

Today’s post is about a nice feature set (many of you have been using for a long time) and its recent improvements. I’m talking about static type checking when type of parameter or variable on the left side of assignment or function return type is explicitly specified in JSDoc annotation. For 5.0 release we’ve supported Google Closure types syntax, so that quite complex situations can be handled more accurately and conveniently.

To start with let’s consider the most basic situation:
@param

Every constructor function “becomes” a type and its name can be referenced inside JSDoc tags.
Array typesArray of elements of some type could also be specified with [] (for example, Point[]).

Return type is checked inside function and when its call result is used somewhere.
Union type

Type checking may even be helpful without explicit types annotations.

And this is my favorite case. You can specify callback’s ‘this’ and parameter types, and they will be known in passed anonymous function. Note that completion processor uses nearly the same info as type checking, so if type is specified in JSDoc annotation, properties of that type will be shown in completion list.

You can always change the type mismatch highlighting style in Settings | Inspections | JavaScript | General | Type mismatch problem to get it more emphasized or disable it at all.

Develop with pleasure!
– JetBrains Web IDE Team

Comments below can no longer be edited.

18 Responses to Validating JavaScript Code with JSDoc Types Annotations

  1. Dylan Greene says:

    October 29, 2012

    I love this feature but it sometimes “guesses” the wrong arguments which leads to unnecessary confusion.

    Is there a way to override the jsdoc it guesses with the right one?

    An example, using Node/Express:


    Server.get('/signin', signIn);

    It thinks .get has no parameters because in Node’s net.js it doesn’t have any (it probably uses arguments to get the parameters).

    • Konstantin Ulitin says:

      October 31, 2012

      You can explicitly declare type with

      /** @type {function(string, *)} */
      Server.get;

      • Dylan Greene says:

        October 31, 2012

        Never thought of such as simple workaround!

        Thank you!

      • Georgiy Ivankin says:

        January 17, 2013

        A great hack! However, it overrides the whole documentation. Is it possible to override part of it, e.g. change type definition but leave the description of function intact?

        • Konstantin Ulitin says:

          January 23, 2013

          Unfortunately, it is not possible now.

      • Spencer O'Reilly says:

        June 30, 2017

        Looking around this seems to be the closest it comes to being an answer to my problem.

        “`
        $element.insertBefore($container);
        “`
        This line has a warning that `insertBefore` has an “Invalid number of arguments, expected 2”

        “`
        /** @type {function(target)} */
        $element.insertBefore;
        $element.insertBefore($container);
        “`
        These three lines have a warning, but for a different reason. The third line no longer has any warning about an invalid number of arguments; however the second line is now concerned that the “Expression statement is not assignment or call”.

        I tried a number of other configurations however none of them seem to affect the first warning in any way… but they don’t create new warnings.
        Some of these variations are as follows:
        “`
        /** @type {function(target)} */
        /* $element.insertBefore; */
        $element.insertBefore($container);
        “`

        “`
        /** @type {function(target)}
        $element.insertBefore; */
        $element.insertBefore($container);
        “`

        “`
        /** @type {function(target)} */
        $element.insertBefore($container);
        “`

        I was just wondering if anyone could give me pointers on what I’m doing wrong or if this warning is just an irreversible mistake for the system right now.

        P.S. This is actually javascript code… I just have a habit of prefacing variables that are instances of jQuery objects with a dollar sign.

        • Spencer O'Reilly says:

          June 30, 2017

          Just in case it helps I also posted this to stackoverflow.

          https://stackoverflow.com/q/44855402/4059832

        • Konstantin Ulitin says:

          July 2, 2017

          /** @function $element.insertBefore */ should do the trick.

          But more recommended way is to add jQuery TypeScript definitions in Settings | JavaScript | Libraries | Download… or by running npm install –save-dev @types/jquery.

  2. New JavaScript inspections and intentions | WebStorm & PhpStorm Blog says:

    November 9, 2012

    […] to improve your coding experience. Besides checks produced by JSDoc annotations described in the previous post, some fresh inspections for JSON, jQuery selectors and other contexts were […]

  3. A M-A says:

    January 14, 2013

    So I’m having trouble documenting AMD style modules. As soon as I have a local variable named the same as my API type it won’t enforce the JSDoc documentation.

    e.g.
    require([‘MyClass’], function (MyClass) {
    var myClass = new MyClass(); //MyClass is documented elsewhere but not enforced
    });

    Any clues on how to do this?

  4. ksafonov says:

    January 23, 2013

    This is not supported at the moment. May I ask you to submit a ticket at http://youtrack.jetbrains.com/issues/WEB? This way others will see it and you will be notified on our progress at the first hand. Thanks!

  5. Oliver Mannion says:

    February 19, 2013

    Love this feature. I have a question though. How do I document a parameter with multiple types. The following:

    @param {function(Ajax.Response | Document)} okCallback

    generates

    Unresolved variable or type ‘Response | Document)’

    • Konstantin Ulitin says:

      February 20, 2013

      You should add parens wrapping these types, i.e.
      @param {function((Ajax.Response | Document))} okCallback

  6. ST says:

    March 6, 2013

    What about validating CoffeeScript code the same way? Do you have plans to implement it?

  7. OuYang says:

    October 11, 2018

    Is there any support for typescript like syntax (https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html) e.g.

    Ts syntax
    @type {(foo: string, bar: string) => string}

    Closure syntax
    @type (function(string, string) : string)

  8. Mallox says:

    November 13, 2018

    Any way to run this stand-alone so that it could be done during an integration test?
    Or maybe somebody knows a package that does something similar without needing the IDE to run?