Skip to content

Commit 634e308

Browse files
committed
fix: support function invocation from imported *.svelte components
When the TypeScript plugin we provide isn't enabled, imports to `.svelte`-files fall back to an ambient module declaration. Said declaration was still only providing the deprecated class. This PR widens the type so that you can also invoke it like a function. After the transition period (Svelte 6 or 7) only the new type should be provided from the module declaration.
1 parent a1b6cc6 commit 634e308

File tree

4 files changed

+39
-2
lines changed

4 files changed

+39
-2
lines changed

.changeset/ninety-days-visit.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
fix: support function invocation from imported `*.svelte` components

packages/svelte/src/ambient.d.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
declare module '*.svelte' {
2-
export { SvelteComponent as default } from 'svelte';
2+
import { SvelteComponent, Component, type ComponentConstructorOptions } from 'svelte';
3+
4+
// Support using the component as both a class and function during the transition period
5+
interface ComponentType {
6+
(
7+
...args: Parameters<Component<Record<string, any>>>
8+
): ReturnType<Component<Record<string, any>, Record<string, any>>>;
9+
new (o: ComponentConstructorOptions): SvelteComponent;
10+
}
11+
const Comp: ComponentType;
12+
type Comp = SvelteComponent;
13+
export default Comp;
314
}
415

516
/**

packages/svelte/tests/types/component.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,13 @@ render(functionComponent, {
281281
x: ''
282282
}
283283
});
284+
285+
// --------------------------------------------------------------------------- *.svelte components
286+
287+
// import from a nonexistent file to trigger the declare module '*.svelte' in ambient.d.ts
288+
// this could show an error in the future in the editor (because language tools intercepts and knows this is an error)
289+
// but should always pass in tsc (because it will never know about this fact)
290+
import Foo from './doesntexist.svelte';
291+
292+
Foo(null, { a: true });
293+
const f: Foo = new Foo({ target: document.body, props: { a: true } });

packages/svelte/types/index.d.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2634,7 +2634,18 @@ declare module 'svelte/types/compiler/interfaces' {
26342634
*/
26352635
type Namespace = 'html' | 'svg' | 'mathml' | 'foreign';
26362636
}declare module '*.svelte' {
2637-
export { SvelteComponent as default } from 'svelte';
2637+
import { SvelteComponent, Component, type ComponentConstructorOptions } from 'svelte';
2638+
2639+
// Support using the component as both a class and function during the transition period
2640+
interface ComponentType {
2641+
(
2642+
...args: Parameters<Component<Record<string, any>>>
2643+
): ReturnType<Component<Record<string, any>, Record<string, any>>>;
2644+
new (o: ComponentConstructorOptions): SvelteComponent;
2645+
}
2646+
const Comp: ComponentType;
2647+
type Comp = SvelteComponent;
2648+
export default Comp;
26382649
}
26392650

26402651
/**

0 commit comments

Comments
 (0)