diff --git a/packages/svelte/src/index.d.ts b/packages/svelte/src/index.d.ts index bf5d5e419e..5a052e3c12 100644 --- a/packages/svelte/src/index.d.ts +++ b/packages/svelte/src/index.d.ts @@ -265,10 +265,7 @@ export type ComponentType = (new element?: typeof HTMLElement; }; -/** - * Internal implementation details that vary between environments - */ -export type SnippetInternals = Branded<{}, 'SnippetInternals'>; +declare const SnippetReturn: unique symbol; // Use an interface instead of a type, makes for better intellisense info because the type is named in more situations. /** @@ -285,12 +282,13 @@ export type SnippetInternals = Branded<{}, 'SnippetInternals'>; export interface Snippet { ( this: void, - internal: SnippetInternals, // this conditional allows tuples but not arrays. Arrays would indicate a // rest parameter type, which is not supported. If rest parameters are added // in the future, the condition can be removed. - ...args: number extends Parameters['length'] ? never : Getters - ): void; + ...args: number extends Parameters['length'] ? never : Parameters + ): typeof SnippetReturn & { + _: 'functions passed to {@render ...} tags must use the `Snippet` type imported from "svelte"'; + }; } interface DispatchOptions { diff --git a/packages/svelte/src/internal/client/dom/blocks/snippet.js b/packages/svelte/src/internal/client/dom/blocks/snippet.js index 846fbd671a..6a6203d16e 100644 --- a/packages/svelte/src/internal/client/dom/blocks/snippet.js +++ b/packages/svelte/src/internal/client/dom/blocks/snippet.js @@ -51,11 +51,10 @@ export function snippet(node, get_snippet, ...args) { * In development, wrap the snippet function so that it passes validation, and so that the * correct component context is set for ownership checks * @param {any} component - * @param {Snippet} fn - * @returns {Snippet} + * @param {(node: TemplateNode, ...args: any[]) => void} fn */ export function wrap_snippet(component, fn) { - return (node, ...args) => { + return (/** @type {TemplateNode} */ node, /** @type {any[]} */ ...args) => { var previous_component_function = dev_current_component_function; set_dev_current_component_function(component); @@ -77,7 +76,8 @@ export function wrap_snippet(component, fn) { * @returns {Snippet} */ export function createRawSnippet(fn) { - return (anchor, ...params) => { + // @ts-expect-error the types are a lie + return (/** @type {TemplateNode} */ anchor, /** @type {Getters} */ ...params) => { var snippet = fn(...params); /** @type {Element} */ @@ -95,7 +95,7 @@ export function createRawSnippet(fn) { w.invalid_raw_snippet_render(); } - /** @type {TemplateNode} */ (/** @type {unknown} */ (anchor)).before(element); + anchor.before(element); } const result = snippet.setup?.(element); diff --git a/packages/svelte/src/internal/server/blocks/snippet.js b/packages/svelte/src/internal/server/blocks/snippet.js index 884f6baa82..d9469be511 100644 --- a/packages/svelte/src/internal/server/blocks/snippet.js +++ b/packages/svelte/src/internal/server/blocks/snippet.js @@ -12,9 +12,10 @@ * @returns {Snippet} */ export function createRawSnippet(fn) { - return (payload, ...args) => { + // @ts-expect-error the types are a lie + return (/** @type {Payload} */ payload, /** @type {Params} */ ...args) => { var getters = /** @type {Getters} */ (args.map((value) => () => value)); - /** @type {Payload} */ (/** @type {unknown} */ (payload)).out += fn(...getters) + payload.out += fn(...getters) .render() .trim(); };