JSDoc difficulties when referencing from npm package.

I have been satisfied with JSDoc for typing over full TypeScript for a while due to being able to do pretty much anything TypeScript can do. Especially when importing from a .ts file is also possible.

However, the following issue around referencing and building types from npm packages has become too much of an issue and waste of time to work around that I can only recommend full TypeScript at this point.

I have included the AI conversation I had to try and resolve this, but the solution in the end is really to just use TypeScript instead.


When I try to use JSDoc types from a file in a library I installed locally via npm, it does not work(in VSCode). Is there no way to get this working?

I’m here to help you get those JSDoc types working in VS Code!

Here are the approaches you can take:

1. Check for Type Declaration Files (.d.ts):

  • If the library includes .d.ts files, VS Code should automatically recognize the types.
  • If not, proceed to the next steps.

2. Generate Type Declaration Files:

  • If the library doesn’t have .d.ts files, you can generate them:
    • Use tools like dts-gen or api-extractor to create them from the library’s source code or JSDoc comments.

3. Reference Types Directly:

  • If you know the specific types you need, reference them directly in your code:

    JavaScript
    /**
     * @param {LibraryName.Type} param - Description of the parameter
     */
    function myFunction(param) {
        // ...
    }
    

4. Manually Create a Declaration File:

  • If the above options aren’t feasible, create a .d.ts file manually:

    TypeScript
    declare module 'library-name' {
        // Define the types here
    }
    

5. Configure VS Code:

  • Check JSDoc support: Ensure “JavaScript and TypeScript: Use JSDoc for IntelliSense” is enabled in VS Code settings.

  • Include additional type roots: If the library types are outside your project, add the path to jsconfig.json or tsconfig.json:

    JSON
    {
        "compilerOptions": {
            "typeRoots": ["./node_modules/@types", "./path/to/library/types"]
        }
    }
    

Additional Troubleshooting:

  • Check for syntax errors: Make sure your JSDoc comments are correct.
  • Restart VS Code: Sometimes a restart fixes type recognition issues.
  • Update extensions: Keep VS Code and related extensions updated.

If you continue to face issues, please provide more details about:

  • The specific library you’re using
  • Your project setup
  • Any error messages you’re encountering

I’ll offer more tailored guidance based on the specific context.

know I can convert to ts, but what about when keeping as JSDoc?

While TypeScript offers superior type safety and integration with VS Code, there are ways to use JSDoc for type definitions in your project even if you prefer to remain in JavaScript:

1. Consider the Approaches Mentioned Previously:

  • Check for existing type declaration files: If the library provides them, VS Code should recognize the types automatically.
  • Manually create a type declaration file: This method requires writing a separate .d.ts file to define the types for the library (explained earlier).
  • Reference types directly: If you know the specific types you need, reference them directly in your code using JSDoc annotations (also explained previously).

2. Ensure JSDoc Support in VS Code:

  • Go to Settings (or Preferences on macOS) and search for “JavaScript and TypeScript: Use JSDoc for IntelliSense.” Make sure it’s checked.
  • This enables VS Code to use JSDoc comments for type information.

3. Address Limitations:

  • Limited IntelliSense: Compared to TypeScript, JSDoc offers less comprehensive IntelliSense. You might encounter scenarios where the code completion or type checking is less robust.
  • Manual Maintenance: Manually maintaining JSDoc comments and ensuring their accuracy can be more work compared to the type checking offered by TypeScript.

In conclusion, while using JSDoc is still an option for type definitions in JavaScript projects, it’s important to be aware of its limitations and potential drawbacks compared to TypeScript. Consider these factors when deciding which approach best suits your project needs and preferences.

It seems VSCode settings do not help and that I need to generate .d.ts files. How can I generate .d.ts file into the library in node_modules.

It’s important to understand that modifying files directly within node_modules is generally not recommended. This directory is managed by npm and changes made to it could be overwritten during future package updates.

Instead, consider the following approaches for generating type declarations without modifying the library in node_modules:

1. Use a Dedicated Folder:

  • Create a separate folder within your project, for example, typings.

  • Use a tool like dts-gen or api-extractor to generate the .d.ts files in this folder.

  • Configure your project (e.g., in tsconfig.json) to include this folder as a source for type definitions:

    JSON
    {
        "compilerOptions": {
            "typeRoots": ["./typings", "./node_modules/@types"]
        }
    }
    

2. Use a Global Typings Repository:

  • Check if the library already has type definitions available in a global repository like @types.

  • If so, install the corresponding package:

    Bash
    npm install --save-dev @types/library-name
    

3. Create a Local Declaration File:

  • Create a .d.ts file within your project and define the types for the library manually.
  • While this approach offers more control, it requires maintaining the type definitions yourself and ensuring they stay in sync with the library.

Remember:

  • Choose the method that best suits your project needs and maintenance preferences.
  • Avoid modifying files directly within node_modules to prevent potential issues.
  • If you decide to create local declarations, consider using a versioning system to track changes.

Research notes regarding converting JSDoc to TypeScript types

A lot of my JS code had been typed with JSDoc comments.
JSDoc comments are very useful for typing JavaScript code, and also have the benefit of allowing inline TypeScript types and importing TypeScript types from ts files. Types can be checked easily in modern editors such as VSCode. For example, the code below, imports from a ts file and types the variable.

/**
* @type {import('tsfile.ts').MyType}
*
const myVariable = 'abc';

It is also possible to declare the type using @typedef to reuse within the file.

/**
* @typedef {import('tsfile.ts').MyType} MyType
*

/*
* @type {MyType}
*/
const myVariable = 'abc';

However, one big issue with JSDoc is that importing it from external libraries seems to not work.
TypeScript types seem to be usable without any processing by just referencing the file such as:

/**
* @typedef {import('my-library'/ts-file-location.ts).MyType} MyType
*/

For JSDoc, generate type declaration files seems to be required.
This is fine, and is expected for JS projects, but it is an extra step that needs to be prepared for all JS projects.

Considering, TypeScript can be imported into JSDoc in the first place, there is really no reason to store type files using JSDoc. The solution is then to isolate types into type only files in ts, and then export each type. This makes it easy to import into JSDoc and into other projects without and processing.

Searching for solutions to convert JSDoc to TypeScript did take my down and long-winding road of issues, that seems to not have been worth the trouble. I have written any significant information in the notes below, but the solution is to just use tsc from TypeScript. See below.

TypeScript tsc

  • Seems to work best. Just need to add exports if necessary and extract from generated file(s).
# Update [SOURCE] below.
# tsc [SOURCE] --declaration --emitDeclarationOnly --allowJs
#
# Notes:
# -- outFile [BUNDLE_DESTINATION] // Works for only some code, so use optionally. https://www.typescriptlang.org/tsconfig/#outFile
# .d.ts file is created in same location with same name before extension.
# To create ts file with exports, SHOULD remove the ".d" part for declaration file, and replace each "type " with "export type ".
# MAY do the same for "interface", but seems like not used (maybe if specifically specified in JSDOC as interface?).
# To prevent replacing wrong code within comments/strings, etc., check that "type" starts at beginning of line.

Notes

ts-migrate

ts-fix

TypeScript codefixes

Other