Skip to content

Commit d93ad3b

Browse files
FoHoOVdummdidumm
andauthored
feat: add ComponentExports utility type (#13441)
Safer/clearer/backwards/forward-compatibale way to reference them --------- Co-authored-by: Simon Holthausen <[email protected]>
1 parent 3999fed commit d93ad3b

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed

.changeset/rotten-cups-float.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+
chore: provide `ComponentExports` utility type

packages/svelte/src/index.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,26 @@ export type ComponentProps<Comp extends SvelteComponent | Component<any, any>> =
237237
? Props
238238
: never;
239239

240+
/**
241+
* Convenience type to get the properties that given component exports.
242+
*
243+
* Example: Typing the `bind:this` for a component named `MyComponent`
244+
* ```
245+
* <script lang="ts">
246+
* import MyComponent from '$lib/component';
247+
* let component: ComponentExports<typeof MyComponent> | undefined = undefined;
248+
* <script>
249+
*
250+
* <MyComponent bind:this={component} />
251+
* ```
252+
*/
253+
export type ComponentExports<TComponent extends Component<any, any> | typeof SvelteComponent<any>> =
254+
TComponent extends typeof SvelteComponent<any>
255+
? InstanceType<TComponent>
256+
: TComponent extends Component<any, infer TExports>
257+
? TExports
258+
: never;
259+
240260
/**
241261
* @deprecated This type is obsolete when working with the new `Component` type.
242262
*

packages/svelte/tests/types/component.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
mount,
88
hydrate,
99
type Component,
10-
type ComponentInternals
10+
type ComponentInternals,
11+
type ComponentExports
1112
} from 'svelte';
1213
import { render } from 'svelte/server';
1314

@@ -180,6 +181,16 @@ render(NewComponent, {
180181
}
181182
});
182183

184+
const newComponentExports: ComponentExports<typeof NewComponent> = {
185+
anExport: '',
186+
$$events_def: null as any,
187+
$$prop_def: null as any,
188+
$$slot_def: null as any,
189+
$set: null as any,
190+
$destroy: null as any,
191+
$on: null as any
192+
};
193+
183194
// --------------------------------------------------------------------------- interop
184195

185196
const AsLegacyComponent = asClassComponent(newComponent);
@@ -337,6 +348,19 @@ render(functionComponent, {
337348
}
338349
});
339350

351+
const functionComponentExports: ComponentExports<typeof functionComponent> = {
352+
foo: 'bar',
353+
// @ts-expect-error
354+
x: ''
355+
};
356+
357+
type AdhocFunctionComponent = (a: unknown, b: { a: true }) => { foo: string };
358+
const adhocFunctionComponentExport: ComponentExports<AdhocFunctionComponent> = {
359+
foo: 'bar',
360+
// @ts-expect-error
361+
x: ''
362+
};
363+
340364
// --------------------------------------------------------------------------- *.svelte components
341365

342366
// import from a nonexistent file to trigger the declare module '*.svelte' in ambient.d.ts

packages/svelte/types/index.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,26 @@ declare module 'svelte' {
234234
? Props
235235
: never;
236236

237+
/**
238+
* Convenience type to get the properties that given component exports.
239+
*
240+
* Example: Typing the `bind:this` for a component named `MyComponent`
241+
* ```
242+
* <script lang="ts">
243+
* import MyComponent from '$lib/component';
244+
* let component: ComponentExports<typeof MyComponent> | undefined = undefined;
245+
* <script>
246+
*
247+
* <MyComponent bind:this={component} />
248+
* ```
249+
*/
250+
export type ComponentExports<TComponent extends Component<any, any> | typeof SvelteComponent<any>> =
251+
TComponent extends typeof SvelteComponent<any>
252+
? InstanceType<TComponent>
253+
: TComponent extends Component<any, infer TExports>
254+
? TExports
255+
: never;
256+
237257
/**
238258
* @deprecated This type is obsolete when working with the new `Component` type.
239259
*

0 commit comments

Comments
 (0)