Skip to content

Support import types in JSDoc links #43950

Open

Description

@mjbvz

Bug Report

🔎 Search Terms

  • JSDoc
  • link / see

🕗 Version & Regression Information

4.3.0-dev.20210503

💻 Code

For some JavaScript:

// foo.js

export class Foo {}
// index.js

/**
 * {@link import('./foo').Foo Foo}
 * 
 * @param {import('./foo').Foo} foo 
 */
function withFoo(foo) { }

🙁 Actual behavior

The parameter type is resolved but the @link is not

🙂 Expected behavior

Both links should be resolved

Activity

  1. olee commented on Nov 15, 2021

    @olee

    Same issue for me - this is especially annoying, because TS and eslint regard type imports which are only used for JSDoc as unused and will request to remove those imports.

  2. marcelocra commented on May 13, 2023

    @marcelocra

    As a workaround, you could use typedef with an import, pointing the link to it:

    /** @typedef {import("./typedefs.js").TheType} TheType */
    
    /**
     * Some doc with a link to the type {@link TheType}.
     */

    Not great, as "go to definition" will take you to this typedef instead of the main one, but at least the correct type is shown when hovering.

  3. jespertheend commented on May 13, 2023

    @jespertheend
    Contributor

    That will cause TheType to be exported twice though (#46011). I usually just end up not linking at all in this situation, because I'd rather not have duplicate entries in my autocomplete list.

  4. ethanresnick commented on Nov 20, 2023

    @ethanresnick
    Contributor

    I would really love to see this too.

    • Linking to other symbols in JSDoc comments is super useful, but adding the import type at the top-level (to get jump-to-definition for that symbol) triggers eslint's no-unused-var rule.

    • Using the no-undefined-types rule from eslint-plugin-jsdoc can solve that (it'll mark the import as used for Eslint), but that rule creates the risk of a non-type-only import that's only used in a JSDoc comment being marked as used, which could lead to unnecessary/unexpected side effects in the verbatimModuleSyntax world.

    • Typescript's organizeImports language feature will automatically remove the import, even if it's referenced in a JSDoc comment.

    Today, I think the best solution is to manually alias the import to start with an _, and configure eslint to not flag variables as unused if they start with an _, but that aliasing is kinda annoying. The import will also still get removed by TS' organizeImports even with the alias.

  5. optyler commented on Dec 5, 2023

    @optyler

    I think my old issue is similar to this one...

    I was trying to @link a function from an imported module from node_module

    Per jsdoc documentation this should be possible

    Link to a module (e.g. within a @link or @see tag) using "module:moduleName". For example, "adel (@module) foo/bar" can be linked to using "{Link (@link) module:foo/bar}".

    I was expecting that these comments link to the function in node_module/date-fns/format but they just render as is

    /**
      * @see module:date-fns/format
      * @link module:date-fns/format
      */
    image
  6. kravetsone commented on Jul 18, 2024

    @kravetsone

    +1

    Why i should import it in top of the module for simple JSDoc link?

  7. esperecyan commented on Aug 1, 2025

    @esperecyan

    In my legacy ESLint setup with .eslintrc.json, I used import type plus eslint-plugin-unused-imports and eslint-plugin-jsdoc to preserve type-only imports referenced only in {@link } comments. After migrating to Flat Config (eslint.config.ts), unused-imports/no-unused-imports now treats those imports as unused and removes them, ignoring their usage in TSDoc comments.

    This makes the issue more urgent in my setup, and I’m really hoping it can be resolved soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions