Skip to content

Commit 39f3d04

Browse files
authored
feat: provide component instance type in Svelte 5 (#2553)
While it's a gotcha for people declaring their own types, the vast majority of people will use component types via importing other components, and as such it makes sense to provide the same convenience we know from class components #2522
1 parent 77c9ccf commit 39f3d04

File tree

18 files changed

+30
-10
lines changed

18 files changed

+30
-10
lines changed

packages/svelte2tsx/src/svelte2tsx/addComponentExport.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,15 @@ function addSimpleComponentExport({
174174

175175
const doc = componentDocumentation.getFormatted();
176176
const className = fileName && classNameFromFilename(fileName, mode !== 'dts');
177+
const componentName = className || '$$Component';
177178

178179
let statement: string;
179180
if (mode === 'dts') {
180181
if (isSvelte5 && exportedNames.usesRunes() && !usesSlots && !events.hasEvents()) {
181182
statement =
182-
`\n${doc}const ${className || '$$Component'} = __sveltets_2_fn_component(render());\n` +
183-
`export default ${className || '$$Component'};`;
183+
`\n${doc}const ${componentName} = __sveltets_2_fn_component(render());\n` +
184+
`type ${componentName} = ReturnType<typeof ${componentName}>;\n` +
185+
`export default ${componentName};`;
184186
} else if (isSvelte5) {
185187
// Inline definitions from Svelte shims; else dts files will reference the globals which will be unresolved
186188
statement =
@@ -203,11 +205,11 @@ function addSimpleComponentExport({
203205
declare function $$__sveltets_2_isomorphic_component<
204206
Props extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>, Exports extends Record<string, any>, Bindings extends string
205207
>(klass: {props: Props, events: Events, slots: Slots, exports?: Exports, bindings?: Bindings }): $$__sveltets_2_IsomorphicComponent<Props, Events, Slots, Exports, Bindings>;\n`) +
206-
`${doc}const ${className || '$$Component'} = $$__sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
208+
`${doc}const ${componentName} = $$__sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
207209
surroundWithIgnoreComments(
208-
`type ${className || '$$Component'} = InstanceType<typeof ${className || '$$Component'}>;\n`
210+
`type ${componentName} = InstanceType<typeof ${componentName}>;\n`
209211
) +
210-
`export default ${className || '$$Component'};`;
212+
`export default ${componentName};`;
211213
} else if (isTsFile) {
212214
const svelteComponentClass = noSvelteComponentTyped
213215
? 'SvelteComponent'
@@ -244,15 +246,16 @@ declare function $$__sveltets_2_isomorphic_component<
244246
if (isSvelte5) {
245247
if (exportedNames.usesRunes() && !usesSlots && !events.hasEvents()) {
246248
statement =
247-
`\n${doc}const ${className || '$$Component'} = __sveltets_2_fn_component(render());\n` +
248-
`export default ${className || '$$Component'};`;
249+
`\n${doc}const ${componentName} = __sveltets_2_fn_component(render());\n` +
250+
`type ${componentName} = ReturnType<typeof ${componentName}>;\n` +
251+
`export default ${componentName};`;
249252
} else {
250253
statement =
251-
`\n${doc}const ${className || '$$Component'} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
254+
`\n${doc}const ${componentName} = __sveltets_2_isomorphic_component${usesSlots ? '_slots' : ''}(${propDef});\n` +
252255
surroundWithIgnoreComments(
253-
`type ${className || '$$Component'} = InstanceType<typeof ${className || '$$Component'}>;\n`
256+
`type ${componentName} = InstanceType<typeof ${componentName}>;\n`
254257
) +
255-
`export default ${className || '$$Component'};`;
258+
`export default ${componentName};`;
256259
}
257260
} else {
258261
statement =

packages/svelte2tsx/test/emitDts/samples/javascript-runes.v5/expected/TestRunes.svelte.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ declare const TestRunes: import("svelte").Component<{
44
}, {
55
baz: () => void;
66
}, "bar">;
7+
type TestRunes = ReturnType<typeof TestRunes>;
78
export default TestRunes;

packages/svelte2tsx/test/emitDts/samples/typescript-runes.v5/expected/TestRunes.svelte.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ declare const TestRunes: import("svelte").Component<{
44
}, {
55
baz: () => void;
66
}, "bar">;
7+
type TestRunes = ReturnType<typeof TestRunes>;
78
export default TestRunes;

packages/svelte2tsx/test/svelte2tsx/samples/export-list-runes.v5/expectedv2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ async () => { { svelteHTML.createElement("svelte:options", {"runes":true,});}
2222
};
2323
return { props: /** @type {Record<string, never>} */ ({}), exports: /** @type {{name1: typeof name1,name2: typeof name2,renamed1: typeof rename1,renamed2: typeof rename2,Foo: typeof Foo,bar: typeof bar,baz: typeof baz,RenamedFoo: typeof RenameFoo,renamedbar: typeof renamebar,renamedbaz: typeof renamebaz}} */ ({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
2424
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
25+
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
2526
export default Input__SvelteComponent_;

packages/svelte2tsx/test/svelte2tsx/samples/renamed-exports-runes.v5/expectedv2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ async () => { { svelteHTML.createElement("svelte:options", {"runes":true,});}
1010
};
1111
return { props: /** @type {Record<string, never>} */ ({}), exports: /** @type {{name3: typeof name,name4: typeof name2}} */ ({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
1212
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
13+
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
1314
export default Input__SvelteComponent_;

packages/svelte2tsx/test/svelte2tsx/samples/runes-best-effort-types.v5/expectedv2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
async () => {};
77
return { props: /** @type {$$ComponentProps} */({}), exports: {}, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
88
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
9+
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
910
export default Input__SvelteComponent_;

packages/svelte2tsx/test/svelte2tsx/samples/runes-bindable.v5/expectedv2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
async () => {};
77
return { props: /** @type {$$ComponentProps} */({}), exports: {}, bindings: __sveltets_$$bindings('b'), slots: {}, events: {} }}
88
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
9+
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
910
export default Input__SvelteComponent_;

packages/svelte2tsx/test/svelte2tsx/samples/runes-looking-like-stores.v5/expectedv2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ async () => {
1010
state; derived;};
1111
return { props: /** @type {$$ComponentProps} */({}), exports: {}, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
1212
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
13+
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
1314
export default Input__SvelteComponent_;

packages/svelte2tsx/test/svelte2tsx/samples/runes-only-export.v5/expectedv2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ async () => {
99
x;};
1010
return { props: /** @type {Record<string, never>} */ ({}), exports: /** @type {{foo: typeof foo}} */ ({}), bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
1111
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
12+
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
1213
export default Input__SvelteComponent_;

packages/svelte2tsx/test/svelte2tsx/samples/runes.v5/expectedv2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
async () => {};
1010
return { props: /** @type {$$ComponentProps} */({}), exports: {}, bindings: __sveltets_$$bindings(''), slots: {}, events: {} }}
1111
const Input__SvelteComponent_ = __sveltets_2_fn_component(render());
12+
type Input__SvelteComponent_ = ReturnType<typeof Input__SvelteComponent_>;
1213
export default Input__SvelteComponent_;

0 commit comments

Comments
 (0)