diff --git a/CHANGELOG.md b/CHANGELOG.md index a29d3bcfb85..f1fc6249c9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* Add a typed `SvelteComponent` interface ([#5431](https://github.com/sveltejs/svelte/pull/5431)) * Fix setting reactive dependencies which don't appear in the template to `undefined` ([#5538](https://github.com/sveltejs/svelte/issues/5538)) * Support preprocessor sourcemaps during compilation ([#5584](https://github.com/sveltejs/svelte/pull/5584)) * Fix ordering of elements when using `{#if}` inside `{#key}` ([#5680](https://github.com/sveltejs/svelte/issues/5680)) diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index 459a78031a0..d107dd39977 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -212,16 +212,19 @@ if (typeof HTMLElement === 'function') { }; } -export class SvelteComponent { +export class SvelteComponent< + Props extends Record = any, + Events extends Record = any +> { $$: T$$; - $$set?: ($$props: any) => void; + $$set?: ($$props: Partial) => void; $destroy() { destroy_component(this, 1); this.$destroy = noop; } - $on(type, callback) { + $on>(type: K, callback: (e: Events[K]) => void) { const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = [])); callbacks.push(callback); @@ -231,7 +234,7 @@ export class SvelteComponent { }; } - $set($$props) { + $set($$props: Partial) { if (this.$$set && !is_empty($$props)) { this.$$.skip_bound = true; this.$$set($$props); diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts index 708b3936013..e93523572fe 100644 --- a/src/runtime/internal/dev.ts +++ b/src/runtime/internal/dev.ts @@ -97,15 +97,44 @@ export function validate_slots(name, slot, keys) { } } -type Props = Record; -export interface SvelteComponentDev { - $set(props?: Props): void; - $on(event: string, callback: (event: CustomEvent) => void): () => void; +export interface SvelteComponentDev< + Props extends Record = any, + Events extends Record = any, + Slots extends Record = any +> { + $set(props?: Partial): void; + $on>(type: K, callback: (e: Events[K]) => void): () => void; $destroy(): void; [accessor: string]: any; } -export class SvelteComponentDev extends SvelteComponent { +export class SvelteComponentDev< + Props extends Record = any, + Events extends Record = any, + Slots extends Record = any +> extends SvelteComponent { + /** + * @private + * For type checking capabilities only. + * Does not exist at runtime. + * ### DO NOT USE! + */ + $$prop_def: Props; + /** + * @private + * For type checking capabilities only. + * Does not exist at runtime. + * ### DO NOT USE! + */ + $$events_def: Events; + /** + * @private + * For type checking capabilities only. + * Does not exist at runtime. + * ### DO NOT USE! + */ + $$slot_def: Slots; + constructor(options: { target: Element; anchor?: Element; @@ -113,7 +142,7 @@ export class SvelteComponentDev extends SvelteComponent { hydrate?: boolean; intro?: boolean; $$inline?: boolean; - }) { + }) { if (!options || (!options.target && !options.$$inline)) { throw new Error("'target' is a required option"); }