sveltejs / language-tools

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

`.d.ts` files missing silently after emit #2371

Open jeannemas opened 1 month ago

jeannemas commented 1 month ago

Describe the bug

Related issues:

Hey! I'd like to maybe bring back the above issue to life, since I believe to have found a consistent way to reproduce it while keeping svelte-check saying everything is fine, which results in missing .d.ts files for some components.

I originally stumbled upon this while working with Shadcn-svelte and vaul-svelte but I believe it affects a lot of other third-party libraries.

TL;DR

The issue is that the .d.ts files are not being generated for some components, while svelte-check says everything is fine, which means that the issue is not being caught by the linter.

My current solution (Gist link)

In order to find the issues (which basically needs to print the .emit() output), I needed to create a modified version of the package script which I've assembled into a Gist.

Gist link scripts/package.js

All of this to say that I believe it is a good idea to handle the emit result and log it out in case of an error, since it might be the only way to find out what's wrong with the .d.ts files generation.

Reproduction

Quick repro using Vaul-Svelte (example)

Expected behaviour

The expected behavior would be to have the .d.ts files generated for all components, or at least have the linter catch the issue.

System Info

From npx envinfo --system --npmPackages svelte,rollup,webpack,bits-ui,@sveltejs/package --binaries --browsers


  System:
    OS: macOS 14.4
    CPU: (8) arm64 Apple M2
    Memory: 116.80 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.1.0 - ~/.nvm/versions/node/v22.1.0/bin/node
    Yarn: 1.22.19 - ~/Library/pnpm/yarn
    npm: 10.7.0 - ~/.nvm/versions/node/v22.1.0/bin/npm
    pnpm: 9.1.0 - ~/Library/pnpm/pnpm
    bun: 0.1.6 - ~/.bun/bin/bun
  Browsers:
    Chrome: 124.0.6367.201
    Safari: 17.4
  npmPackages:
    @sveltejs/package: ^2.0.0 => 2.2.5 
    bits-ui: ^0.16.0 => 0.16.0 
    svelte: ^4.2.7 => 4.2.8 

Which package is the issue about?

svelte2tsx, svelte-check

Additional Information, eg. Screenshots

No response

jasonlyu123 commented 1 month ago

TypeScript only reports this diagnostic when building declaration so we might not be able to show in svelte-check. But when it comes to diagnostics in emitDts, as mentioned in #1835, the diagnostics might contain a lot of weird things and false positives. So if we were to report the diagnostics, we might need to keep track of a list of diagnostics code that only reports in the declaration building. If the list contains the code we print it out else have a generic message to redirect users to use svelte-check.

jasonlyu123 commented 1 month ago

TypeScript actually also checks declaration diagnostics when the file's type-check is disabled with // @ts-nocheck. So we could slap the directive to the top of the generated ts file to disable type-check and we should be able to print out the diagnostics. But since the diagnostic is very likely to point to a generated code we'll need to enhance the message and not print out the problematic code.

In the reproduction library, there are 2 types of issues. One is fixed in the latest version of svelte2tsx so we'll ignore it here. The other one has messages like

src/lib/vaul/components/close.svelte.ts:61:7 - error TS2742: The inferred type of '__propDef' cannot be named without a reference to '.pnpm/@melt-ui+svelte@0.76.2_svelte@4.2.17/node_modules/@melt-ui/svelte/internal/types'. This is likely not portable. A type annotation is necessary.

61 const __propDef = __sveltets_2_with_any_event(render());

Turns out the type of slot props is referencing @melte-ui/svelte. And because of pmpm's strict dependency, the path can't be imported directly and therefore can't be rewritten into a module specifier. It is very hard to tell from the message And this is also something that can't be fixed on our generated code. We can probably detect the word __propDef and rewrite it as generated component definition In other cases, we can only enhance it when we encounter it.