skip to Main Content

Problem

I am finding that JSDoc works well with intellisense and type checking when the JSDoc-typed code is "inside" the project; however, including a JSDoc-typed library via a script tag (<script src="mylibrary.js">) does NOT provide any intellisense, type checking, or hints.

My intention is to publish a library with types included, and I had hoped that JSDoc would allow me to do that even for users who wanted to include the script via tag rather than installing and importing with NPM, where a .d.ts file would suffice.

I appreciate any insight anyone can provide.

Assumptions

My guess is that the TypeScript checker can’t access code included in a script tag, even if that script is local, but since I have seen nothing that outright states that, I wanted to check my understanding here. I’m a TypeScript user but am new to JSDoc, so I may be missing some nuance here.

Details

I am using VSCode with Microsoft’s "JavaScript and TypeScript Nightly" plugin.

My library code works something like this:

/**
 * @preserve
 * @typedef {object} LibObj - The main library object
 * @property {string} LibObj.name - The name of the library
 */
globalThis.LibObj = {
  name: "My Library's Name"
}

When I include the library code into my HTML page, LibObj and LibObj.name have an any type and I get no intellisense.

2

Answers


  1. Chosen as BEST ANSWER

    @myf's response and comments to my original post were extremely helpful in setting me on the right path. There were still some issues getting this to work (probably due to my own misunderstanding of how TypeScript's JSDoc support works), so I will post some additional findings here.

    Much of this has to do with implementation details that didn't seem relevant to the issue, and so I was not transparent enough about them in the original question.

    1. As @myf indicated, intellisense will pick up types when the file containing those types is open, and will forget about them when it's closed. That's where /// <reference path=""> comes in handy.
    2. Keeping the file with the types open or using the triple-slash comment will not help you in a script tag within an HTML file. The script has to be a .js file.
    3. Watch your build tools! I had my bundler set to roll everything into an IIFE, which is an immediately-invoked function. Since my typed global LibObj object was declared within the function and not at the top-level, the TypeScript linter didn't pick it up.
    4. Just a caution -- this is actually something I was doing correctly -- if you are minifying, make sure to use @preserve for any JSDoc that you don't want minified away, and set your minifier accordingly. For terser, you need to set the comments option to "some."

  2. It is quite straightforward. Assuming Visual Studio Code environment.

    If your intended usage for users is they will have page.html with

    <script src="mylibrary.js"></script><!-- your library -->
    <script src="script.js"></script><!-- their script using your library -->
    

    then you should instruct them to add triple slash directive

    /// <reference path="mylibrary.js" />
    

    at the beginning of their script.js, optionally along with // @ts-check comment directive and perhaps //@module JSDoc directive.

    This way the language server will know for sure what library.js provides and include it in the intellisense and type checking in the script.js.


    Fig:

    library.js:

    /**
     * @preserve
     * @typedef {object} LibObj - The main library object
     * @property {string} LibObj.name - The name of the library
     */
    /** @type {LibObj} */
    globalThis.LibObj = {
      name: "My Library's Name"
    }
    

    script.js:

    /// <reference path="library.js" />
    
    LibObj.
    

    Having cursor at the end of the script.js and asking for suggestions yields:

    VS Code with two files open, showing tooltip working intellisense suggestion suggesting type and description in the first file imported from the second.

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