diff --git a/packages/svelte/src/attachments/index.js b/packages/svelte/src/attachments/index.js index ec568f1bcc..514c9433f4 100644 --- a/packages/svelte/src/attachments/index.js +++ b/packages/svelte/src/attachments/index.js @@ -1,7 +1,5 @@ -/** - * @import { Attachment } from "./public.js"; - * @import { ActionReturn } from "svelte/action"; - */ +/** @import { Action, ActionReturn } from 'svelte/action' */ +/** @import { Attachment } from 'svelte/attachments' */ import { noop, render_effect } from 'svelte/internal/client'; import { ATTACHMENT_KEY } from '../constants.js'; import { untrack } from 'svelte'; @@ -34,35 +32,41 @@ export function createAttachmentKey() { } /** - * @template {EventTarget} [Element=HTMLElement] - * @template {*} [Par=unknown] - * @typedef {( - * ...args: (undefined extends NoInfer - * ? [ - * action: (node: Node, parameter?: never) => void | ActionReturn, - * parameter?: () => NoInfer - * ] - * : [ - * action: (node: Node, parameter: Parameter) => void | ActionReturn, - * parameter: () => NoInfer - * ]) - * ) => Attachment} FromAction + * @template {EventTarget} E + * @template {unknown} T + * @overload + * @param {Action | function(E, T): void | ActionReturn} action The action function + * @param {() => T} fn A function that returns the argument for the action + * @returns {Attachment} + */ +/** + * @template {EventTarget} E + * @overload + * @param {Action | function(E): void | ActionReturn} action The action function + * @returns {Attachment} */ - /** * Converts an Action into an Attachment keeping the same behavior. It's useful if you want to start using * attachments on Components but you have library provided actions. - * @type {FromAction} + * + * Note that the second argument, if provided, must be a function that _returns_ the argument to the + * action function, not the argument itself. + * + * @template {EventTarget} E + * @template {unknown} T + * @param {Action | function(E, T): void | ActionReturn} action The action function + * @param {() => T} fn A function that returns the argument for the action + * @returns {Attachment} * @since 5.32 */ -export function fromAction(action, /** @type {() => any} */ get_arg = noop) { +export function fromAction(action, fn = /** @type {() => T} */ (noop)) { return (element) => { - const { update, destroy } = untrack(() => action(element, get_arg()) ?? {}); + const { update, destroy } = untrack(() => action(element, fn()) ?? {}); if (update) { var ran = false; render_effect(() => { - const arg = get_arg(); + const arg = fn(); if (ran) update(arg); }); ran = true; diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index d1b3ecd9d5..067e04db5b 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -625,7 +625,7 @@ declare module 'svelte/animate' { } declare module 'svelte/attachments' { - import type { ActionReturn } from 'svelte/action'; + import type { ActionReturn, Action } from 'svelte/action'; /** * An [attachment](https://svelte.dev/docs/svelte/@attach) is a function that runs when an element is mounted * to the DOM, and optionally returns a function that is called when the element is later removed. @@ -659,8 +659,10 @@ declare module 'svelte/attachments' { * @since 5.29 */ export function createAttachmentKey(): symbol; - export function fromAction(...args: undefined extends NoInfer ? [action: (node: Node, parameter?: never) => void | ActionReturn, parameter?: (() => NoInfer) | undefined] : [action: (node: Node, parameter: Parameter) => void | ActionReturn, parameter: () => NoInfer]): Attachment; - export type FromAction = (...args: (undefined extends NoInfer ? [action: (node: Node, parameter?: never) => void | ActionReturn, parameter?: () => NoInfer] : [action: (node: Node, parameter: Parameter) => void | ActionReturn, parameter: () => NoInfer])) => Attachment; + + export function fromAction(action: Action | ((arg0: E, arg1: T) => void | ActionReturn), fn: () => T): Attachment; + + export function fromAction(action: Action | ((arg0: E) => void | ActionReturn)): Attachment; export {}; }