language-tools
language-tools copied to clipboard
TypeScript warning when using <svelte:element/> with sveltekit:prefetch attribute
Describe the bug
I have a Button component that renders a dynamic tag using svelte:element. Sometimes it renders anchor tags, so I have applied sveltekit:prefetch to the element, but TypeScript complains that svelte:element doesn't support that attribute. The attribute still works as expected: when an anchor tag is rendered, the sveltekit:prefetch attribute is present and triggers the desired prefetching behavior on hover. When a different tag (e.g. button) is rendered, the sveltekit:prefetch attribute is also present, but seems to have no adverse effect.
Is there a 'valid' way to use this attribute on this element? Should the type definition of svelte:element be expanded to allow this usage?
Reproduction
I have a REPL explaining the issue, and the use case behind it, here: https://svelte.dev/repl/bfbeb5c43f21461c9cbd0fea3cd680cb?version=3.49.0
Logs
No response
System Info
System:
OS: macOS 12.5
CPU: (10) arm64 Apple M1 Pro
Memory: 107.34 MB / 32.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.15.1 - /usr/local/bin/node
Yarn: 1.22.19 - ~/.yarn/bin/yarn
npm: 8.11.0 - /usr/local/bin/npm
Browsers:
Chrome: 104.0.5112.79
Firefox: 101.0.1
Safari: 15.6
Safari Technology Preview: 16.0
npmPackages:
@sveltejs/adapter-auto: next => 1.0.0-next.63
@sveltejs/kit: next => 1.0.0-next.393
svelte: ^3.44.0 => 3.49.0
vite: ^3.0.0 => 3.0.3
Severity
annoyance
Additional Information
No response
Hmmm. I would think this is correct behavior. In pure TypeScript you could do some type narrowing to make this work, but I'm not sure if there's a way to do that in markup.
In the meantime, I bet this would work:
{#if selected === 'a'}
<a />
{:else}
<svelte:element />
{/if}
That does unfortunately force you to duplicate the wiring up of props, but I'd think it's the most "correct" way to do what you want to do.
I'd say this is purely a TS error which in this case we should fix, we can't know what svelte:element is so we should allow all attributes. Moving this to language-tools.
There are kinda two issues here:
- the typescript error
- sveltekit:prefetch being adding where not needed (e.g. on a button)
so I wonder if the sveltekit:prefetch attribute could be modified to accept an expression, e.g.
<svelte:element this={tag} sveltekit:prefetch={tag === 'a'}>
similar to other 'true if present' attributes, like disabled which can be conditionalized with disabled={expression}.
I'd say this is purely a TS error which in this case we should fix, we can't know what
svelte:elementis so we should allow all attributes. Moving this to language-tools.
Interesting -- I would've thought the allowable attributes on an unknown element would be the intersection of allowable attributes for every HTML element, not any, but I suppose being permissive is also a valid approach (and makes more sense now that I think about it!). Thanks. 🙂
By "all attributes" I meant what you mean, all valid attributes of all elements + the special ones (that's the problem here) 👍