Skip to content

Commit 05f99d2

Browse files
feat: move svelteHTML to load the correct svelte/element (#9070)
Make IntrinsicElements extends SvelteHTMLElements so it can be extend with declare module converting to module so it can extend without needing another type alias --------- Co-authored-by: Simon H <[email protected]>
1 parent 8b1cdde commit 05f99d2

File tree

4 files changed

+276
-0
lines changed

4 files changed

+276
-0
lines changed

.changeset/slimy-dingos-call.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': minor
3+
---
4+
5+
feat: move `svelteHTML` from language-tools into core to load the correct `svelte/element` types

documentation/docs/05-misc/03-typescript.md

+18
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,24 @@ declare namespace svelteHTML {
140140

141141
Then make sure that `d.ts` file is referenced in your `tsconfig.json`. If it reads something like `"include": ["src/**/*"]` and your `d.ts` file is inside `src`, it should work. You may need to reload for the changes to take effect.
142142

143+
Since Svelte version 4.2 / `svelte-check` version 3.5 / VS Code extension version 107.10.0 you can also declare the typings by augmenting the the `svelte/elements` module like this:
144+
145+
```js
146+
/// file: additional-svelte-typings.d.ts
147+
import { HTMLButtonAttributes } from 'svelte/elements'
148+
149+
declare module 'svelte/elements' {
150+
export interface SvelteHTMLElements {
151+
'custom-button': HTMLButtonAttributes;
152+
}
153+
154+
// allows for more granular control over what element to add the typings to
155+
export interface HTMLButtonAttributes {
156+
'veryexperimentalattribute'?: string;
157+
}
158+
}
159+
```
160+
143161
## Experimental advanced typings
144162

145163
A few features are missing from taking full advantage of TypeScript in more advanced use cases like typing that a component implements a certain interface, explicitly typing slots, or using generics. These things are possible using experimental advanced type capabilities. See [this RFC](https://github.com/dummdidumm/rfcs/blob/ts-typedefs-within-svelte-components/text/ts-typing-props-slots-events.md) for more information on how to make use of them.

packages/svelte/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"motion.d.ts",
2020
"action.d.ts",
2121
"elements.d.ts",
22+
"svelte-html.d.ts",
2223
"README.md"
2324
],
2425
"exports": {

packages/svelte/svelte-html.d.ts

+252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
/// <reference lib="dom" />
2+
// This file is deliberately not exposed through the exports map.
3+
// It's meant to be loaded directly by the Svelte language server
4+
/* eslint-disable @typescript-eslint/no-empty-interface */
5+
6+
import * as svelteElements from './elements.js';
7+
8+
/**
9+
* @internal do not use
10+
*/
11+
type HTMLProps<Property extends string, Override> = Omit<
12+
import('./elements.js').SvelteHTMLElements[Property],
13+
keyof Override
14+
> &
15+
Override;
16+
17+
declare global {
18+
/**
19+
* This namespace does not exist in the runtime, it is only used for typings
20+
*/
21+
namespace svelteHTML {
22+
// Every namespace eligible for use needs to implement the following two functions
23+
/**
24+
* @internal do not use
25+
*/
26+
function mapElementTag<K extends keyof ElementTagNameMap>(tag: K): ElementTagNameMap[K];
27+
function mapElementTag<K extends keyof SVGElementTagNameMap>(tag: K): SVGElementTagNameMap[K];
28+
function mapElementTag(tag: any): any; // needs to be any because used in context of <svelte:element>
29+
30+
/**
31+
* @internal do not use
32+
*/
33+
function createElement<Elements extends IntrinsicElements, Key extends keyof Elements>(
34+
// "undefined | null" because of <svelte:element>
35+
element: Key | undefined | null,
36+
attrs: string extends Key ? svelteElements.HTMLAttributes<any> : Elements[Key]
37+
): Key extends keyof ElementTagNameMap
38+
? ElementTagNameMap[Key]
39+
: Key extends keyof SVGElementTagNameMap
40+
? SVGElementTagNameMap[Key]
41+
: any;
42+
function createElement<Elements extends IntrinsicElements, Key extends keyof Elements, T>(
43+
// "undefined | null" because of <svelte:element>
44+
element: Key | undefined | null,
45+
attrsEnhancers: T,
46+
attrs: (string extends Key ? svelteElements.HTMLAttributes<any> : Elements[Key]) & T
47+
): Key extends keyof ElementTagNameMap
48+
? ElementTagNameMap[Key]
49+
: Key extends keyof SVGElementTagNameMap
50+
? SVGElementTagNameMap[Key]
51+
: any;
52+
53+
// For backwards-compatibility and ease-of-use, in case someone enhanced the typings from import('svelte/elements').HTMLAttributes/SVGAttributes
54+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
55+
interface HTMLAttributes<T extends EventTarget = any> {}
56+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
57+
interface SVGAttributes<T extends EventTarget = any> {}
58+
59+
/**
60+
* Avoid using this interface directly. Instead use the `SvelteHTMLElements` interface exported by `svelte/elements`
61+
* This should only be used if you need to extend the interface with custom elements
62+
*/
63+
interface IntrinsicElements extends svelteElements.SvelteHTMLElements {
64+
a: HTMLProps<'a', HTMLAttributes>;
65+
abbr: HTMLProps<'abbr', HTMLAttributes>;
66+
address: HTMLProps<'address', HTMLAttributes>;
67+
area: HTMLProps<'area', HTMLAttributes>;
68+
article: HTMLProps<'article', HTMLAttributes>;
69+
aside: HTMLProps<'aside', HTMLAttributes>;
70+
audio: HTMLProps<'audio', HTMLAttributes>;
71+
b: HTMLProps<'b', HTMLAttributes>;
72+
base: HTMLProps<'base', HTMLAttributes>;
73+
bdi: HTMLProps<'bdi', HTMLAttributes>;
74+
bdo: HTMLProps<'bdo', HTMLAttributes>;
75+
big: HTMLProps<'big', HTMLAttributes>;
76+
blockquote: HTMLProps<'blockquote', HTMLAttributes>;
77+
body: HTMLProps<'body', HTMLAttributes>;
78+
br: HTMLProps<'br', HTMLAttributes>;
79+
button: HTMLProps<'button', HTMLAttributes>;
80+
canvas: HTMLProps<'canvas', HTMLAttributes>;
81+
caption: HTMLProps<'caption', HTMLAttributes>;
82+
cite: HTMLProps<'cite', HTMLAttributes>;
83+
code: HTMLProps<'code', HTMLAttributes>;
84+
col: HTMLProps<'col', HTMLAttributes>;
85+
colgroup: HTMLProps<'colgroup', HTMLAttributes>;
86+
data: HTMLProps<'data', HTMLAttributes>;
87+
datalist: HTMLProps<'datalist', HTMLAttributes>;
88+
dd: HTMLProps<'dd', HTMLAttributes>;
89+
del: HTMLProps<'del', HTMLAttributes>;
90+
details: HTMLProps<'details', HTMLAttributes>;
91+
dfn: HTMLProps<'dfn', HTMLAttributes>;
92+
dialog: HTMLProps<'dialog', HTMLAttributes>;
93+
div: HTMLProps<'div', HTMLAttributes>;
94+
dl: HTMLProps<'dl', HTMLAttributes>;
95+
dt: HTMLProps<'dt', HTMLAttributes>;
96+
em: HTMLProps<'em', HTMLAttributes>;
97+
embed: HTMLProps<'embed', HTMLAttributes>;
98+
fieldset: HTMLProps<'fieldset', HTMLAttributes>;
99+
figcaption: HTMLProps<'figcaption', HTMLAttributes>;
100+
figure: HTMLProps<'figure', HTMLAttributes>;
101+
footer: HTMLProps<'footer', HTMLAttributes>;
102+
form: HTMLProps<'form', HTMLAttributes>;
103+
h1: HTMLProps<'h1', HTMLAttributes>;
104+
h2: HTMLProps<'h2', HTMLAttributes>;
105+
h3: HTMLProps<'h3', HTMLAttributes>;
106+
h4: HTMLProps<'h4', HTMLAttributes>;
107+
h5: HTMLProps<'h5', HTMLAttributes>;
108+
h6: HTMLProps<'h6', HTMLAttributes>;
109+
head: HTMLProps<'head', HTMLAttributes>;
110+
header: HTMLProps<'header', HTMLAttributes>;
111+
hgroup: HTMLProps<'hgroup', HTMLAttributes>;
112+
hr: HTMLProps<'hr', HTMLAttributes>;
113+
html: HTMLProps<'html', HTMLAttributes>;
114+
i: HTMLProps<'i', HTMLAttributes>;
115+
iframe: HTMLProps<'iframe', HTMLAttributes>;
116+
img: HTMLProps<'img', HTMLAttributes>;
117+
input: HTMLProps<'input', HTMLAttributes>;
118+
ins: HTMLProps<'ins', HTMLAttributes>;
119+
kbd: HTMLProps<'kbd', HTMLAttributes>;
120+
keygen: HTMLProps<'keygen', HTMLAttributes>;
121+
label: HTMLProps<'label', HTMLAttributes>;
122+
legend: HTMLProps<'legend', HTMLAttributes>;
123+
li: HTMLProps<'li', HTMLAttributes>;
124+
link: HTMLProps<'link', HTMLAttributes>;
125+
main: HTMLProps<'main', HTMLAttributes>;
126+
map: HTMLProps<'map', HTMLAttributes>;
127+
mark: HTMLProps<'mark', HTMLAttributes>;
128+
menu: HTMLProps<'menu', HTMLAttributes>;
129+
menuitem: HTMLProps<'menuitem', HTMLAttributes>;
130+
meta: HTMLProps<'meta', HTMLAttributes>;
131+
meter: HTMLProps<'meter', HTMLAttributes>;
132+
nav: HTMLProps<'nav', HTMLAttributes>;
133+
noscript: HTMLProps<'noscript', HTMLAttributes>;
134+
object: HTMLProps<'object', HTMLAttributes>;
135+
ol: HTMLProps<'ol', HTMLAttributes>;
136+
optgroup: HTMLProps<'optgroup', HTMLAttributes>;
137+
option: HTMLProps<'option', HTMLAttributes>;
138+
output: HTMLProps<'output', HTMLAttributes>;
139+
p: HTMLProps<'p', HTMLAttributes>;
140+
param: HTMLProps<'param', HTMLAttributes>;
141+
picture: HTMLProps<'picture', HTMLAttributes>;
142+
pre: HTMLProps<'pre', HTMLAttributes>;
143+
progress: HTMLProps<'progress', HTMLAttributes>;
144+
q: HTMLProps<'q', HTMLAttributes>;
145+
rp: HTMLProps<'rp', HTMLAttributes>;
146+
rt: HTMLProps<'rt', HTMLAttributes>;
147+
ruby: HTMLProps<'ruby', HTMLAttributes>;
148+
s: HTMLProps<'s', HTMLAttributes>;
149+
samp: HTMLProps<'samp', HTMLAttributes>;
150+
slot: HTMLProps<'slot', HTMLAttributes>;
151+
script: HTMLProps<'script', HTMLAttributes>;
152+
section: HTMLProps<'section', HTMLAttributes>;
153+
select: HTMLProps<'select', HTMLAttributes>;
154+
small: HTMLProps<'small', HTMLAttributes>;
155+
source: HTMLProps<'source', HTMLAttributes>;
156+
span: HTMLProps<'span', HTMLAttributes>;
157+
strong: HTMLProps<'strong', HTMLAttributes>;
158+
style: HTMLProps<'style', HTMLAttributes>;
159+
sub: HTMLProps<'sub', HTMLAttributes>;
160+
summary: HTMLProps<'summary', HTMLAttributes>;
161+
sup: HTMLProps<'sup', HTMLAttributes>;
162+
table: HTMLProps<'table', HTMLAttributes>;
163+
template: HTMLProps<'template', HTMLAttributes>;
164+
tbody: HTMLProps<'tbody', HTMLAttributes>;
165+
td: HTMLProps<'td', HTMLAttributes>;
166+
textarea: HTMLProps<'textarea', HTMLAttributes>;
167+
tfoot: HTMLProps<'tfoot', HTMLAttributes>;
168+
th: HTMLProps<'th', HTMLAttributes>;
169+
thead: HTMLProps<'thead', HTMLAttributes>;
170+
time: HTMLProps<'time', HTMLAttributes>;
171+
title: HTMLProps<'title', HTMLAttributes>;
172+
tr: HTMLProps<'tr', HTMLAttributes>;
173+
track: HTMLProps<'track', HTMLAttributes>;
174+
u: HTMLProps<'u', HTMLAttributes>;
175+
ul: HTMLProps<'ul', HTMLAttributes>;
176+
var: HTMLProps<'var', HTMLAttributes>;
177+
video: HTMLProps<'video', HTMLAttributes>;
178+
wbr: HTMLProps<'wbr', HTMLAttributes>;
179+
webview: HTMLProps<'webview', HTMLAttributes>;
180+
// SVG
181+
svg: HTMLProps<'svg', SVGAttributes>;
182+
183+
animate: HTMLProps<'animate', SVGAttributes>;
184+
animateMotion: HTMLProps<'animateMotion', SVGAttributes>;
185+
animateTransform: HTMLProps<'animateTransform', SVGAttributes>;
186+
circle: HTMLProps<'circle', SVGAttributes>;
187+
clipPath: HTMLProps<'clipPath', SVGAttributes>;
188+
defs: HTMLProps<'defs', SVGAttributes>;
189+
desc: HTMLProps<'desc', SVGAttributes>;
190+
ellipse: HTMLProps<'ellipse', SVGAttributes>;
191+
feBlend: HTMLProps<'feBlend', SVGAttributes>;
192+
feColorMatrix: HTMLProps<'feColorMatrix', SVGAttributes>;
193+
feComponentTransfer: HTMLProps<'feComponentTransfer', SVGAttributes>;
194+
feComposite: HTMLProps<'feComposite', SVGAttributes>;
195+
feConvolveMatrix: HTMLProps<'feConvolveMatrix', SVGAttributes>;
196+
feDiffuseLighting: HTMLProps<'feDiffuseLighting', SVGAttributes>;
197+
feDisplacementMap: HTMLProps<'feDisplacementMap', SVGAttributes>;
198+
feDistantLight: HTMLProps<'feDistantLight', SVGAttributes>;
199+
feDropShadow: HTMLProps<'feDropShadow', SVGAttributes>;
200+
feFlood: HTMLProps<'feFlood', SVGAttributes>;
201+
feFuncA: HTMLProps<'feFuncA', SVGAttributes>;
202+
feFuncB: HTMLProps<'feFuncB', SVGAttributes>;
203+
feFuncG: HTMLProps<'feFuncG', SVGAttributes>;
204+
feFuncR: HTMLProps<'feFuncR', SVGAttributes>;
205+
feGaussianBlur: HTMLProps<'feGaussianBlur', SVGAttributes>;
206+
feImage: HTMLProps<'feImage', SVGAttributes>;
207+
feMerge: HTMLProps<'feMerge', SVGAttributes>;
208+
feMergeNode: HTMLProps<'feMergeNode', SVGAttributes>;
209+
feMorphology: HTMLProps<'feMorphology', SVGAttributes>;
210+
feOffset: HTMLProps<'feOffset', SVGAttributes>;
211+
fePointLight: HTMLProps<'fePointLight', SVGAttributes>;
212+
feSpecularLighting: HTMLProps<'feSpecularLighting', SVGAttributes>;
213+
feSpotLight: HTMLProps<'feSpotLight', SVGAttributes>;
214+
feTile: HTMLProps<'feTile', SVGAttributes>;
215+
feTurbulence: HTMLProps<'feTurbulence', SVGAttributes>;
216+
filter: HTMLProps<'filter', SVGAttributes>;
217+
foreignObject: HTMLProps<'foreignObject', SVGAttributes>;
218+
g: HTMLProps<'g', SVGAttributes>;
219+
image: HTMLProps<'image', SVGAttributes>;
220+
line: HTMLProps<'line', SVGAttributes>;
221+
linearGradient: HTMLProps<'linearGradient', SVGAttributes>;
222+
marker: HTMLProps<'marker', SVGAttributes>;
223+
mask: HTMLProps<'mask', SVGAttributes>;
224+
metadata: HTMLProps<'metadata', SVGAttributes>;
225+
mpath: HTMLProps<'mpath', SVGAttributes>;
226+
path: HTMLProps<'path', SVGAttributes>;
227+
pattern: HTMLProps<'pattern', SVGAttributes>;
228+
polygon: HTMLProps<'polygon', SVGAttributes>;
229+
polyline: HTMLProps<'polyline', SVGAttributes>;
230+
radialGradient: HTMLProps<'radialGradient', SVGAttributes>;
231+
rect: HTMLProps<'rect', SVGAttributes>;
232+
stop: HTMLProps<'stop', SVGAttributes>;
233+
switch: HTMLProps<'switch', SVGAttributes>;
234+
symbol: HTMLProps<'symbol', SVGAttributes>;
235+
text: HTMLProps<'text', SVGAttributes>;
236+
textPath: HTMLProps<'textPath', SVGAttributes>;
237+
tspan: HTMLProps<'tspan', SVGAttributes>;
238+
use: HTMLProps<'use', SVGAttributes>;
239+
view: HTMLProps<'view', SVGAttributes>;
240+
241+
// Svelte specific
242+
'svelte:window': HTMLProps<'svelte:window', HTMLAttributes>;
243+
'svelte:body': HTMLProps<'svelte:body', HTMLAttributes>;
244+
'svelte:document': HTMLProps<'svelte:document', HTMLAttributes>;
245+
'svelte:fragment': { slot?: string };
246+
'svelte:options': HTMLProps<'svelte:options', HTMLAttributes>;
247+
'svelte:head': { [name: string]: any };
248+
249+
[name: string]: { [name: string]: any };
250+
}
251+
}
252+
}

0 commit comments

Comments
 (0)