sveltejs/language-tools

Repository tracker

Pull requests

chore: support function for compilerOptions

#2623
Dec 10, 2024
For svelte2tsx we gotta make a compromise - since everything has to be sync, we can only pass the unpreprocessed file. Should be fine in practise because a preprocessor influencing the code in such a way that it in turn influences the compiler options is probably vanishingly rare. https://github.com/sveltejs/svelte/issues/12415

chore: fix dts jsdoc test

#2572
Nov 7, 2024
Noticed that this test doesn't really do what it says it should do. But the output is a bit concerning, I'm not sure why TS creates it that way. We might need to tweak our dts output generation, not sure yet how such that it will output the right thing. Keeping this open until we solve it; as a reminder.

fix: allow JS snapshots within TS plugin

#2565
Nov 6, 2024
So far we've always assumed that a Svelte file is a TS file for simplicity, due to our default language (which was removed a long time ago) and also because IIRC there were issues with TS having its snapshot scriptKind being switched. That seems to be no longer the case, and so we can get better at properly analyzing whether or not this is a TS file, to allow JSDoc to take action when it's a JS file. #2555 @jasonlyu123 do you remember why that scriptKind switch broke previously, but apparently doesn't anymore? I vaguely remember us having the same problem within the language server, but you PRd a change at some point stating that it's no longer a problem. Also, is this a breaking change, because if someone has no allowJS in their config they would get errors?

(perf) WIP: TS incremental parsing

#1192
Nov 5, 2024
Implement getChangeRange of the ScriptSnapshot interface so TS can incrementally parse the result of svelte2tsx. TODO: Doesn't reliably work, gets into a broken state seemginly random after some time Update: Found a bug in the implementation, works now Wasn't able to prove this is really faster (how to best test this?). Update: Tested this with VS Code's Dev Tools and it doesn't change much. It's about 2-5miliseconds that are saved, which feels like very little. @jasonlyu123 thoughts?

chore: optimize svelte-check bundle size

#2544
Oct 27, 2024
Following Ben's effort to trim down the size. I was actually trying to add some glob library back because chokidar v4 removed the glob support entirely() so was trying to trim it to balance it out 😆. The difference seems relatively large. The bulk of it seems to be HTML custom data which took around 500KB.

feat: resolve Svelte components using TS from exports map

#2478
Aug 30, 2024
This change allows people to write export maps using only a svelte condition (and no types condition) and still have the types for their components resolved (i.e. the import is found) as long as they use TypeScript (i.e. have lang="ts" attribute) inside it. This should help people using monorepo setups with strong typings and not wanting to provide d.ts files alongside. This is achieved doing three adjustments: add customConditions: ['svelte'] to the compiler options, so that TypeScript's resolution algorithm takes it into account ensure that Svelte files have a module kind of ESM, so that TypeScript's resolution algorithm goes into the right branches no longer needed since the switch to using .d.svelte.ts as the "virtual file check" entry point deal with .d.svelte.ts files in the context of an exports map, because that's what TypeScript will try to resolve this to in the end This is also related to #1056 insofar that we align with TypeScript for this new capability: We don't resolve the file if it's a component not using TypeScript (i.e. not having the lang="ts" tag), similar to how TypeScript does not resolve .js files within node_modules As a side effect, this is a major version bump for language-tools and the typescript plugin, and consequently for svelte-check/vs code extension

feat: add editor label and formatter configuration defaults

#2330
Apr 21, 2024
Uses the VS Code extension configuration defaults contribution point to: set the default formatter for svelte files as mentioned in the README (which some people may have missed) uses the new VS Code custom labels setting to append the directory name to the editor label for SvelteKit +page and +server files. Default
default editor labels
Label format "workbench.editor.labelFormat": "short"
label format: short
Custom labels "workbench.editor.customLabels.patterns": { "**/+page.*": "${dirname}/${filename}.${extname}", "**/+server.*": "${dirname}/${filename}.${extname}", },
custom vscode editor labels

Issues

Remove <svelte:html> for the time being

#2787
6 days ago • Jun 25, 2025
We should revert #2599 until https://github.com/sveltejs/svelte/pull/14397 gets merged.

enhanced:img tag not recognised as img

#2321
May 5, 2025
Describe the bug Following the @sveltejs/enhanced-img docs, we can style images by targeting them as img. https://kit.svelte.dev/docs/images#sveltejs-enhanced-img-intrinsic-dimensions However, this shows an unused css warning when using the Svelte VSCode extension
CleanShot 2024-03-23 at 10  56 07@2x
Reproduction https://github.com/eltigerchino/svelte-enhanced-image clone the repo and open the root page in vs code with the svelte extension Expected behaviour There should be no warning. System Info OS: [MacOS] IDE: [VSCode] Which package is the issue about? Svelte for VS Code extension Additional Information, eg. Screenshots No response

Snippets and their argument types not correctly resolved from generic legacy components

#2716
Apr 29, 2025
Describe the bug Using a legacy component with slots via snippets, the available snippets may not be resolved correctly and arguments passed to the snippets end up as any. Reproduction <!-- loader.svelte --> <script lang="ts" generics="T"> interface $$Slots { default: { value: T }, loaded: { value: T }, loading: { }, error: { error: any }, } export let promise: Promise<T>; </script> {#await promise} <slot name="loading"> Loading... </slot> {:then value} <slot {value} /> <slot name="loaded" {value} /> {:catch} Error! {/await} <script lang="ts"> import Loader from './loader.svelte'; const delay = (ms: number) => new Promise(resolve => setTimeout(() => resolve(ms), ms)); const promise = delay(1000).then(() => "resolved"); </script> <Loader promise={promise}> <!-- Error on `loading`: Object literal may only specify known properties, and 'loading' does not exist in type '{ promise: Promise<string>; } & { children?: any; }'. ts(2353) --> {#snippet loading()} Loading text... {/snippet} <!-- Error on `value`: <!-- Binding element 'value' implicitly has an 'any' type. ts(7031) --> {#snippet loaded({ value })} Text: {value} {/snippet} {#snippet error()} Error. {/snippet} </Loader> (The runtime behavior is correct.) Expected behaviour loading is detected as a valid slot/snippet. value is generically typed correctly (here string). System Info OS: Windows 10, 64bit IDE: VSCode 1.98.2 Which package is the issue about? Svelte for VS Code extension Additional Information, eg. Screenshots Extension & svelte-check yield same errors. If the loading snippet is not there, the next snippet will show an error, only promise & children are detected as valid properties.

Auto import rune files (.svelte.js/.svelte.ts) files with full extension.

#2620
Jan 6, 2025
Description If a symbol from a .svelte.js file is selected from a suggestion dropdown in VS Code, the added import lacks the .js extension. If the extension is missing, this can cause conflicts with components that share the prefix, it also is plain confusing to the uninitiated since it looks like a component is being imported. Proposed solution Always import as .svelte.js, not sure if this is possible though. (Maybe use .svelte.ts if state of TS's allowImportingTsExtensions can be detected.) Alternatives No response Additional Information, eg. Screenshots No response

@link tags don't work in .svelte files

#2604
Nov 25, 2024
Describe the bug Doc comments with @link tags are no longer clickable links when rendered to their tooltip within a .svelte file. Reproduction The following interface: interface FooBar { foo: 1 bar: 2 /** * Sum of {@link foo} and {@link bar} */ foo_bar: 3 } When placed (or imported) into a .svelte file, no longer shows clickable links.
Screenshot 2024-11-24 at 11 06 18 PM
Expected behaviour In a .ts file, foo and bar are clickable links:
Screenshot 2024-11-24 at 11 06 54 PM
System Info OS: MacOS IDE: Cursor / VSCode Which package is the issue about? Svelte for VS Code extension Additional Information, eg. Screenshots No response

rename --preserveWatchOutput to --preserve-watch-output

#2550
Nov 5, 2024
We use hyphenated flags elsewhere e.g. --compiler-warnings and --diagnostic-sources

breaking: use parseArgs from Node 18.3

#2521
Sep 26, 2024
Description We can drop multiple dependencies (sade/mri) from svelte-check when bumping engines to 18.3 Proposed solution import { parseArgs } from 'node:util'; Alternatives No response Additional Information, eg. Screenshots No response

Performance: skip jsdoc parsing in various places

#2170
Sep 1, 2024
May result in microscopic wins, every milisecond counts: https://github.com/microsoft/TypeScript/pull/55739 Can use this in svelte2tsx, maybe other locations, too. Usable in TS 5.3+

Quick fix for adding $state(...) wrapper.

#2470
Aug 21, 2024
Description When manually migrating a component to runes, a quick fix for non_reactive_update would be useful. E.g. adding the first $state will highlight all issues on other variables: <script lang="ts"> let a = $state(1); let b = 2; // "`b` is updated, but is not declared with `$state(...)`. ..." let c: number; // "`c` is updated, but is not declared with `$state(...)`. ..." </script> <!-- [bind to/update values] --> Proposed solution Add quick fix options that add $state to the currently highlighted or all variables with the warning. Add $state(...) Add $state(...) for all <script lang="ts"> let a = $state(1); - let b = 2; + let b = $state(2); - let c: number; + let c: number = $state(); </script> (For c this would be a type error, but the resolution of that should probably be up to the user. I am assuming pre-existing migration logic would be used here if possible.) Possibly some other quick fixes/refactoring involving $derived and $effect could be added for $: (legacy_reactive_statement_invalid). Alternatives No response Additional Information, eg. Screenshots No response

Zero effort type safety for inlined enhance callback

#2410
Jun 21, 2024
Description It would be nice if the inlined enhance callback could be auto typed to the SubmitFunction type from ./$types in +page.svelte files. Since typescript in the template is not supported in Svelte < 5, it would probably only be possible for projects that use Svelte 5. Or is it possible with JSDoc? Proposed solution Auto type the callback. Alternatives No response Additional Information, eg. Screenshots No response

Emit dts not respecting abs path

#2182
May 14, 2024
Describe the bug When I use emitDts with an absolute path, and I am in a subfolder from my project it weirdly saves it to a path like this: /workspace/extractinator/workspace/extractinator/.temp await emitDts({ svelteShimsPath: require.resolve('svelte2tsx/svelte-shims-v4.d.ts'), declarationDir: '/workspace/extractinator/.temp', libRoot: '/workspace/extractinator/playground', }) Reproduction I can provide a repo if this isn't just user error or expected - which I worry it is Expected behaviour It to save it at the given path System Info OS: ubuntu docker IDE: vscode Which package is the issue about? svelte2tsx Additional Information, eg. Screenshots No response

Svelte 5 various tasks

#2280
Apr 25, 2024
Description Non-committing TODO list of things we want to look at for Svelte 5 from an intellisense perspective Proposed solution revisit #1308 fix bugs remove context from SnippetBlock code, was used in an early .next version .. Alternatives No response Additional Information, eg. Screenshots No response

Weird behavior with Generics + SvelteHTMLElement

#2271
Jan 26, 2024
Describe the bug I was creating an "isomorphic component" (basically where you pass as and it render the correct html element) and i started experimenting with the typings to get autocompletion. I come up with this which works fine <script lang="ts" generics="T extends keyof HTMLElementTagNameMap"> import type { SvelteHTMLElements } from 'svelte/elements'; export let as: T; type $$Props = SvelteHTMLElements[T] & { as: T; }; </script> the typecheck per se works fine but what is a bit iffy it's the autocompletion. You get autocomplete for every prop even the one that are not associated with the type T (for example you get autocomplete for type if you use spam for as). I tried the same generic function in the typescript playground and it works correctly. https://github.com/sveltejs/language-tools/assets/26281609/1bfdc057-5cb0-42f2-b3b1-d1a0a9886dc8 https://github.com/sveltejs/language-tools/assets/26281609/403a5a65-8d27-4200-b28d-9d76d895fb9d Reproduction go to this TS playground https://tsplay.dev/NB1Gpw verify that autocomplete works correctly paste the above code in a svelte component in vscode try to import it and get autocompletion Expected behaviour You should only get autocompletion for the correct element System Info OS: Mac IDE: VSCode Which package is the issue about? No response Additional Information, eg. Screenshots No response

Consider removing the Omit type from the HTMLProps type

#2225
Jan 2, 2024
This type in our d.ts file in svelte2tsx: type HTMLProps<Property extends string, Override> = Omit<import('svelte/elements').SvelteHTMLElements[Property], keyof Override> & Override; Results in the data-${string} type overriding any more narrow types like data-sveltekit-... In other words, I can pass an invalid value to data-sveltekit-.. and it doesn't error, because the fallback type overrides it so that anything is allowed. The question now is: Should we simplify the HTMLProps type to import('svelte/elements').SvelteHTMLElements[Property] & Override? The one drawback is that you cannot pass properties that have conflicting types anymore. Given that you rarely want to override a type (you mainly want to add new ones), and in case you do want to override them, you mostly want to narrow them (which is fine with the simplified type, too), I lean towards making this change. @jasonlyu123 thoughts?