Skip to content

Commit c35f0c1

Browse files
authored
fix: deduplicate module declaration, adjust type (#10801)
- the `component` parameter expects a component constructor type, not an instance type - use `import('svelte')` instead of relative paths to not inline all types that are already present in the sibiling module declaration
1 parent ffb27f6 commit c35f0c1

File tree

3 files changed

+11
-176
lines changed

3 files changed

+11
-176
lines changed

packages/svelte/src/legacy/legacy-client.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import * as $ from '../internal/index.js';
1111
* @template {Record<string, any>} Events
1212
* @template {Record<string, any>} Slots
1313
*
14-
* @param {import('../main/public.js').ComponentConstructorOptions<Props> & {
15-
* component: import('../main/public.js').SvelteComponent<Props, Events, Slots>;
14+
* @param {import('svelte').ComponentConstructorOptions<Props> & {
15+
* component: import('svelte').ComponentType<import('svelte').SvelteComponent<Props, Events, Slots>>;
1616
* immutable?: boolean;
1717
* hydrate?: boolean;
1818
* recover?: boolean;
1919
* }} options
20-
* @returns {import('../main/public.js').SvelteComponent<Props, Events, Slots> & Exports}
20+
* @returns {import('svelte').SvelteComponent<Props, Events, Slots> & Exports}
2121
*/
2222
export function createClassComponent(options) {
2323
// @ts-expect-error $$prop_def etc are not actually defined
@@ -34,8 +34,8 @@ export function createClassComponent(options) {
3434
* @template {Record<string, any>} Events
3535
* @template {Record<string, any>} Slots
3636
*
37-
* @param {import('../main/public.js').SvelteComponent<Props, Events, Slots>} component
38-
* @returns {import('../main/public.js').ComponentType<import('../main/public.js').SvelteComponent<Props, Events, Slots> & Exports>}
37+
* @param {import('svelte').SvelteComponent<Props, Events, Slots>} component
38+
* @returns {import('svelte').ComponentType<import('svelte').SvelteComponent<Props, Events, Slots> & Exports>}
3939
*/
4040
export function asClassComponent(component) {
4141
// @ts-expect-error $$prop_def etc are not actually defined
@@ -58,7 +58,7 @@ class Svelte4Component {
5858
#instance;
5959

6060
/**
61-
* @param {import('../main/public.js').ComponentConstructorOptions & {
61+
* @param {import('svelte').ComponentConstructorOptions & {
6262
* component: any;
6363
* immutable?: boolean;
6464
* hydrate?: boolean;

packages/svelte/tests/types/component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,5 +170,5 @@ asLegacyComponent.anExport;
170170
const x: typeof asLegacyComponent = createClassComponent({
171171
target: null as any,
172172
hydrate: true,
173-
component: newComponent
173+
component: NewComponent
174174
});

packages/svelte/types/index.d.ts

Lines changed: 4 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,184 +1728,19 @@ declare module 'svelte/legacy' {
17281728
* @deprecated Use this only as a temporary solution to migrate your imperative component code to Svelte 5.
17291729
*
17301730
* */
1731-
export function createClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(options: ComponentConstructorOptions<Props> & {
1732-
component: SvelteComponent<Props, Events, Slots>;
1731+
export function createClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(options: import("svelte").ComponentConstructorOptions<Props> & {
1732+
component: import("svelte").ComponentType<import("svelte").SvelteComponent<Props, Events, Slots>>;
17331733
immutable?: boolean | undefined;
17341734
hydrate?: boolean | undefined;
17351735
recover?: boolean | undefined;
1736-
}): SvelteComponent<Props, Events, Slots> & Exports;
1736+
}): import("svelte").SvelteComponent<Props, Events, Slots> & Exports;
17371737
/**
17381738
* Takes the component function and returns a Svelte 4 compatible component constructor.
17391739
*
17401740
* @deprecated Use this only as a temporary solution to migrate your imperative component code to Svelte 5.
17411741
*
17421742
* */
1743-
export function asClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(component: SvelteComponent<Props, Events, Slots>): ComponentType<SvelteComponent<Props, Events, Slots> & Exports>;
1744-
// This should contain all the public interfaces (not all of them are actually importable, check current Svelte for which ones are).
1745-
1746-
/**
1747-
* @deprecated Svelte components were classes in Svelte 4. In Svelte 5, thy are not anymore.
1748-
* Use `mount` or `createRoot` instead to instantiate components.
1749-
* See [breaking changes](https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes)
1750-
* for more info.
1751-
*/
1752-
interface ComponentConstructorOptions<
1753-
Props extends Record<string, any> = Record<string, any>
1754-
> {
1755-
target: Element | Document | ShadowRoot;
1756-
anchor?: Element;
1757-
props?: Props;
1758-
context?: Map<any, any>;
1759-
hydrate?: boolean;
1760-
intro?: boolean;
1761-
$$inline?: boolean;
1762-
}
1763-
1764-
// Utility type for ensuring backwards compatibility on a type level: If there's a default slot, add 'children' to the props if it doesn't exist there already
1765-
type PropsWithChildren<Props, Slots> = Props &
1766-
(Props extends { children?: any }
1767-
? {}
1768-
: Slots extends { default: any }
1769-
? { children?: Snippet }
1770-
: {});
1771-
1772-
/**
1773-
* Can be used to create strongly typed Svelte components.
1774-
*
1775-
* #### Example:
1776-
*
1777-
* You have component library on npm called `component-library`, from which
1778-
* you export a component called `MyComponent`. For Svelte+TypeScript users,
1779-
* you want to provide typings. Therefore you create a `index.d.ts`:
1780-
* ```ts
1781-
* import { SvelteComponent } from "svelte";
1782-
* export class MyComponent extends SvelteComponent<{foo: string}> {}
1783-
* ```
1784-
* Typing this makes it possible for IDEs like VS Code with the Svelte extension
1785-
* to provide intellisense and to use the component like this in a Svelte file
1786-
* with TypeScript:
1787-
* ```svelte
1788-
* <script lang="ts">
1789-
* import { MyComponent } from "component-library";
1790-
* </script>
1791-
* <MyComponent foo={'bar'} />
1792-
* ```
1793-
*
1794-
* This was the base class for Svelte components in Svelte 4. Svelte 5+ components
1795-
* are completely different under the hood. You should only use this type for typing,
1796-
* not actually instantiate components with `new` - use `mount` or `createRoot` instead.
1797-
* See [breaking changes](https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes)
1798-
* for more info.
1799-
*/
1800-
class SvelteComponent<
1801-
Props extends Record<string, any> = any,
1802-
Events extends Record<string, any> = any,
1803-
Slots extends Record<string, any> = any
1804-
> {
1805-
[prop: string]: any;
1806-
/**
1807-
* @deprecated This constructor only exists when using the `asClassComponent` compatibility helper, which
1808-
* is a stop-gap solution. Migrate towards using `mount` or `createRoot` instead. See
1809-
* https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more info.
1810-
*/
1811-
constructor(options: ComponentConstructorOptions<PropsWithChildren<Props, Slots>>);
1812-
/**
1813-
* For type checking capabilities only.
1814-
* Does not exist at runtime.
1815-
* ### DO NOT USE!
1816-
* */
1817-
$$prop_def: PropsWithChildren<Props, Slots>;
1818-
/**
1819-
* For type checking capabilities only.
1820-
* Does not exist at runtime.
1821-
* ### DO NOT USE!
1822-
*
1823-
* */
1824-
$$events_def: Events;
1825-
/**
1826-
* For type checking capabilities only.
1827-
* Does not exist at runtime.
1828-
* ### DO NOT USE!
1829-
*
1830-
* */
1831-
$$slot_def: Slots;
1832-
1833-
/**
1834-
* @deprecated This method only exists when using one of the legacy compatibility helpers, which
1835-
* is a stop-gap solution. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes
1836-
* for more info.
1837-
*/
1838-
$destroy(): void;
1839-
1840-
/**
1841-
* @deprecated This method only exists when using one of the legacy compatibility helpers, which
1842-
* is a stop-gap solution. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes
1843-
* for more info.
1844-
*/
1845-
$on<K extends Extract<keyof Events, string>>(
1846-
type: K,
1847-
callback: (e: Events[K]) => void
1848-
): () => void;
1849-
1850-
/**
1851-
* @deprecated This method only exists when using one of the legacy compatibility helpers, which
1852-
* is a stop-gap solution. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes
1853-
* for more info.
1854-
*/
1855-
$set(props: Partial<Props>): void;
1856-
}
1857-
1858-
/**
1859-
* Convenience type to get the type of a Svelte component. Useful for example in combination with
1860-
* dynamic components using `<svelte:component>`.
1861-
*
1862-
* Example:
1863-
* ```html
1864-
* <script lang="ts">
1865-
* import type { ComponentType, SvelteComponent } from 'svelte';
1866-
* import Component1 from './Component1.svelte';
1867-
* import Component2 from './Component2.svelte';
1868-
*
1869-
* const component: ComponentType = someLogic() ? Component1 : Component2;
1870-
* const componentOfCertainSubType: ComponentType<SvelteComponent<{ needsThisProp: string }>> = someLogic() ? Component1 : Component2;
1871-
* </script>
1872-
*
1873-
* <svelte:component this={component} />
1874-
* <svelte:component this={componentOfCertainSubType} needsThisProp="hello" />
1875-
* ```
1876-
*/
1877-
type ComponentType<Comp extends SvelteComponent = SvelteComponent> = (new (
1878-
options: ComponentConstructorOptions<
1879-
Comp extends SvelteComponent<infer Props> ? Props : Record<string, any>
1880-
>
1881-
) => Comp) & {
1882-
/** The custom element version of the component. Only present if compiled with the `customElement` compiler option */
1883-
element?: typeof HTMLElement;
1884-
};
1885-
1886-
const SnippetReturn: unique symbol;
1887-
1888-
/**
1889-
* The type of a `#snippet` block. You can use it to (for example) express that your component expects a snippet of a certain type:
1890-
* ```ts
1891-
* let { banner }: { banner: Snippet<{ text: string }> } = $props();
1892-
* ```
1893-
* You can only call a snippet through the `{@render ...}` tag.
1894-
*/
1895-
type Snippet<T extends unknown[] = []> =
1896-
// this conditional allows tuples but not arrays. Arrays would indicate a
1897-
// rest parameter type, which is not supported. If rest parameters are added
1898-
// in the future, the condition can be removed.
1899-
number extends T['length']
1900-
? never
1901-
: {
1902-
(
1903-
this: void,
1904-
...args: T
1905-
): typeof SnippetReturn & {
1906-
_: 'functions passed to {@render ...} tags must use the `Snippet` type imported from "svelte"';
1907-
};
1908-
};
1743+
export function asClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(component: import("svelte").SvelteComponent<Props, Events, Slots>): import("svelte").ComponentType<import("svelte").SvelteComponent<Props, Events, Slots> & Exports>;
19091744
}
19101745

19111746
declare module 'svelte/motion' {

0 commit comments

Comments
 (0)