feat: auto-generate .svelte.d.ts for dependency packages in incremental/tsgo mode#2967
feat: auto-generate .svelte.d.ts for dependency packages in incremental/tsgo mode#2967datstarkey wants to merge 2 commits intosveltejs:masterfrom
Conversation
…al/tsgo mode The svelte-check docs for --incremental and --tsgo state: "Specifically, anything that is not in the root dir of your tsconfig.json and is a Svelte file will not be properly loaded and type-checked." In a monorepo where workspace packages export .svelte components (e.g. via pnpm workspace links), this means svelte-check --tsgo or --incremental cannot type-check those components - all props resolve to `any`. The only workaround is pre-building every workspace package with `svelte-package` to generate .d.ts files, adding an unnecessary build step to the type-checking workflow. This commit addresses the limitation by automatically detecting dependency packages that contain .svelte files without companion .d.ts declarations and generating virtual declarations for them using svelte2tsx, the same way the app's own .svelte files are already handled. How it works: - Scans direct dependencies (via package.json + node_modules) for .svelte files that lack a companion .svelte.d.ts - Runs svelte2tsx on each to emit virtual .ts/.d.ts into the existing .svelte-check cache directory - Adds rootDirs entries pairing each package's real path with its emit directory, so tsc/tsgo can find the declarations Known limitations / areas for improvement: - Currently processes ALL .svelte files in each dependency package, not just the ones actually imported by the app. A smarter approach would trace the import graph to only process referenced files. - This is an initial approach and may benefit from refinement based on real-world feedback from different monorepo setups.
|
|
Thanks for the contribution. Have you tried this, or is this all AI-generated? I don't think your solution works. Adding the generated directory to |
|
So i did test this on my particular use case and it did solve the problem, but not the core underlying problem. In my particular case I have a monorepo with a couple of frontend sveltekte projects, some in static adatper, 2 with node adapter etc. All these share 2 projects in a worksace repo, for api and shared. so the project structure is like packages
Each has its own tsconfig and svelte.config.js then at root i have a pnpm-workspace.yaml with a catalogue for all the same package versions across them. the shared project is also dependant on the api project bla bla bla. so i had a turbo repo setup with a svelte package build step for the shared package, whcih worked but was a a bit slow, about 6-8 minutes for the whole build. I then conisidered taking out the build step entirely, which shaved it down to less than 2 minutes for the entire build (no cache) stack, using barreled sub path exports directly. "exports": {
"./components": {
"types": "./src/lib/components/index.ts",
"svelte": "./src/lib/components/index.ts"
},
}this resulted in the builds working fine, but check with --incremental or --tsgo would fail on the any types and lots of Error: Module '"*.svelte"' has no exported member 'blablabla'. this resolves the typing issue by pulling it and storing the .d.ts, however it doesnt give errors on the shared files, it jsut allows us to keep the types for use in our frontend app. a check still needs to be run on the shared package for proper svelte diagnostics. I have a replication here: https://github.com/datstarkey/svelte-check-monorepo-repro tbh its wholey possible im using a monorepo wrong in this case, I did try with project references and paths aswell but couldn't get anything to work so gave this a bash instead. |
|
Sorry, but I didn't see any difference. Both the current 4.4.4 and your fix reports 0 errors when there should be errors. |
|
Actually, i just deleted my node modules and .svelte-kit folders and tried again and now it saying 0 errors, will have a look at this and why it worked the first time for me |
|
OKAY, you need to run svelte-kit sync so the .svelte-check folder is inside .svelte-kit thats a bug ill fix in the PR, but ive updated the repro to run sync first then check which shows it working atleast for now, may neeed to delete the .svelte-check folder first EDIT: |
|
Yeah, I did build svelte-check in the submodule and have run |
|
Ill check on my windows machien later aswell. I updaetd the repro to check (no --tsgo) and check:go (using --tsgo) in app one (using the fix) and app two (using old). for me in app two, there are 3 errors with no tsgo and no errors with tsgo |
|
Ok. It does work on Linux, so there's probably a bug on Windows. I think the reason it works is:
This means if you have a I am not really sure if we should dig more into this rabbit hole 😅 I think if there isn't a good enough solution, I would prefer not do this and wait for TypeScript team to come up with a proper API. |
|
yeah in perspective this is a super hacky workaround, and if its not working on windows. I'll close this in favour of an offical ts api, the real approach here is to have a build step with svelte pacakge, as thats still faster than running the non incremental/tsgo svelte check. |

Problem
The svelte-check docs for
--incrementaland--tsgostate:In a monorepo where workspace packages export
.sveltecomponents (e.g. via pnpm workspace links), this meanssvelte-check --tsgoor--incrementalcannot type-check those components — all props resolve toany. The only workaround today is pre-building every workspace package withsvelte-packageto generate.d.tsfiles, adding an unnecessary build step to the type-checking workflow.Solution
This PR addresses the limitation by automatically detecting dependency packages that contain
.sveltefiles without companion.d.tsdeclarations and generating virtual declarations for them using svelte2tsx — the same mechanism already used for the app's own.sveltefiles.How it works
package.json+node_modules) for.sveltefiles that lack a companion.svelte.d.tsor.d.svelte.tssvelte2tsxon each to emit virtual.ts/.d.tsinto the existing.svelte-checkcache directory, mirroring the package's internal directory structurerootDirsentries pairing each package's real path with its emit directory, so tsc/tsgo can find the virtual declarations when resolving.svelteimportsResolution flow
Known limitations / areas for improvement
.sveltefiles in each dependency package, not just the ones actually imported by the app. A smarter approach would trace the import graph to only process referenced files..sveltefiles are excluded from Svelte compiler diagnostics reporting (only TS diagnostics from tsc/tsgo are reported for them).Test plan
.sveltecomponents: 0 errors, 3587 files checked (without anysvelte-packagepre-build step)