sveltejs / language-tools

The Svelte Language Server, and official extensions which use it
MIT License
1.26k stars 200 forks source link

Autoimport uses TS syntax when using JSDoc mode #2503

Open razshare opened 2 months ago

razshare commented 2 months ago

Describe the bug

When importing a type using JSDoc, the autoimport solution uses TS syntax to import the type, instead of using JSDoc syntax. Peek 2024-09-14 18-49

Reproduction

Reproduction can be found here - https://github.com/razshare/svelte5-language-tools-jsdoc-autoimport-issue

Or simply create a new sveltekit project

npm create svelte@latest my-app

Make sure to pick the JSDoc option when prompted. The Svelte 5 option is required for this one example, but trying to import Svelte 4 packages will result in the same issue.

Then paste this into any component

<script>
  /** @type {{header:Snippet,content:Snippet,footer:Snippet}}*/
  let { header, content, footer } = $props();
</script>

<div class="card">
  <div class="hreader">
    {@render header()}
  </div>
  <div class="content">
    {@render content()}
  </div>
  <div class="footer">
    {@render footer()}
  </div>
</div>

Expected behaviour

When trying to import Snippet using the language tools (ctrl+space), the solution should import the type using JSDoc syntax.

So the result should look like this

<script>
  /** @type {{header:import('svelte').Snippet,content:import('svelte').Snippet,footer:import('svelte').Snippet}}*/
  let { header, content, footer } = $props();
</script>

<div class="card">
  <div class="hreader">
    {@render header()}
  </div>
  <div class="content">
    {@render content()}
  </div>
  <div class="footer">
    {@render footer()}
  </div>
</div>

Or like this

<script>
  /**
   * @typedef {import('svelte').Snippet} Snippet
   */

  /** @type {{header:Snippet,content:Snippet,footer:Snippet}}*/
  let { header, content, footer } = $props();
</script>

<div class="card">
  <div class="hreader">
    {@render header()}
  </div>
  <div class="content">
    {@render content()}
  </div>
  <div class="footer">
    {@render footer()}
  </div>
</div>

Or even this, using ts >= 5.5

<script>
  /**
   * @import { Snippet } from "svelte"
   */

  /** @type {{header:Snippet,content:Snippet,footer:Snippet}}*/
  let { header, content, footer } = $props();
</script>

<div class="card">
  <div class="hreader">
    {@render header()}
  </div>
  <div class="content">
    {@render content()}
  </div>
  <div class="footer">
    {@render footer()}
  </div>
</div>

System Info

Which package is the issue about?

Svelte for VS Code extension

Additional Information, eg. Screenshots

No response

jasonlyu123 commented 2 months ago

Hmm... This one is hard to fix from our side. TypeScript provides the auto-import but they judge if the file is a js file with the file extension instead of ScriptKind API that we can override. Also, This specific case is a recent regression. We need to ask them if this can be changed back but still retain what the change is for. It might also be possible we have to rewrite the suggestion but it'll be hard.