From 472bb7742a951953671d088ec7272c59a3175f6e Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 28 Jun 2023 23:49:43 +0200 Subject: [PATCH] same for action --- .changeset/long-humans-dress.md | 2 +- .../docs/05-misc/04-v4-migration-guide.md | 4 ++-- .../svelte/src/runtime/action/public.d.ts | 17 +++++++---------- packages/svelte/test/types/actions.ts | 19 ++++++++----------- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/.changeset/long-humans-dress.md b/.changeset/long-humans-dress.md index 68502950f7..bc9cf8b40e 100644 --- a/.changeset/long-humans-dress.md +++ b/.changeset/long-humans-dress.md @@ -2,4 +2,4 @@ 'svelte': patch --- -fix: ensure createEventDispatcher works with types from generics +fix: ensure `createEventDispatcher` and `ActionReturn` work with types from generic function parameters diff --git a/documentation/docs/05-misc/04-v4-migration-guide.md b/documentation/docs/05-misc/04-v4-migration-guide.md index 81749a4ba9..7da5f3e118 100644 --- a/documentation/docs/05-misc/04-v4-migration-guide.md +++ b/documentation/docs/05-misc/04-v4-migration-guide.md @@ -50,10 +50,10 @@ dispatch('required'); // error, missing argument dispatch('noArgument', 'surprise'); // error, cannot pass an argument ``` -- `Action` and `ActionReturn` have a default parameter type of `never` now, which means you need to type the generic if you want to specify that this action receives a parameter. The migration script will migrate this automatically ([#7442](https://github.com/sveltejs/svelte/pull/7442)) +- `Action` and `ActionReturn` have a default parameter type of `undefined` now, which means you need to type the generic if you want to specify that this action receives a parameter. The migration script will migrate this automatically ([#7442](https://github.com/sveltejs/svelte/pull/7442)) ```diff --const action: Action = (node, params) => { .. } // this is now an error, as params is expected to not exist +-const action: Action = (node, params) => { .. } // this is now an error if you use params in any way +const action: Action = (node, params) => { .. } // params is of type string ``` diff --git a/packages/svelte/src/runtime/action/public.d.ts b/packages/svelte/src/runtime/action/public.d.ts index d52b8a726a..afd92e116d 100644 --- a/packages/svelte/src/runtime/action/public.d.ts +++ b/packages/svelte/src/runtime/action/public.d.ts @@ -1,8 +1,8 @@ /** * Actions can return an object containing the two properties defined in this interface. Both are optional. * - update: An action can have a parameter. This method will be called whenever that parameter changes, - * immediately after Svelte has applied updates to the markup. `ActionReturn` and `ActionReturn` both - * mean that the action accepts no parameters, which makes it illegal to set the `update` method. + * immediately after Svelte has applied updates to the markup. `ActionReturn` and `ActionReturn` both + * mean that the action accepts no parameters. * - destroy: Method that is called after the element is unmounted * * Additionally, you can specify which additional attributes and events the action enables on the applied element. @@ -27,10 +27,10 @@ * Docs: https://svelte.dev/docs/svelte-action */ export interface ActionReturn< - Parameter = never, + Parameter = undefined, Attributes extends Record = Record > { - update?: [Parameter] extends [never] ? never : (parameter: Parameter) => void; + update?: (parameter: Parameter) => void; destroy?: () => void; /** * ### DO NOT USE THIS @@ -50,7 +50,7 @@ export interface ActionReturn< * // ... * } * ``` - * `Action` and `Action` both signal that the action accepts no parameters. + * `Action` and `Action` both signal that the action accepts no parameters. * * You can return an object with methods `update` and `destroy` from the function and type which additional attributes and events it has. * See interface `ActionReturn` for more details. @@ -59,13 +59,11 @@ export interface ActionReturn< */ export interface Action< Element = HTMLElement, - Parameter = never, + Parameter = undefined, Attributes extends Record = Record > { ( - ...args: [Parameter] extends [never] - ? [node: Node] - : undefined extends Parameter + ...args: undefined extends Parameter ? [node: Node, parameter?: Parameter] : [node: Node, parameter: Parameter] ): void | ActionReturn; @@ -73,4 +71,3 @@ export interface Action< // Implementation notes: // - undefined extends X instead of X extends undefined makes this work better with both strict and nonstrict mode -// - [X] extends [never] is needed, X extends never would reduce the whole resulting type to never and not to one of the condition outcomes diff --git a/packages/svelte/test/types/actions.ts b/packages/svelte/test/types/actions.ts index 03659e7605..da4e660a1a 100644 --- a/packages/svelte/test/types/actions.ts +++ b/packages/svelte/test/types/actions.ts @@ -65,30 +65,27 @@ const optional4: Action = (_node, _param?) => }; optional4; -const no: Action = (_node) => {}; +const no: Action = (_node) => {}; // @ts-expect-error second param no(null as any, true); no(null as any); // @ts-expect-error second param no(null as any, 'string'); -const no1: Action = (_node) => { +const no1: Action = (_node) => { return { destroy: () => {} }; }; no1; -// @ts-expect-error param given -const no2: Action = (_node, _param?) => {}; -no2; +const no2: Action = (_node, _param?) => {}; +no2(null as any); -// @ts-expect-error param given -const no3: Action = (_node, _param) => {}; +const no3: Action = (_node, _param) => {}; no3; -// @ts-expect-error update method given -const no4: Action = (_node) => { +const no4: Action = (_node) => { return { update: () => {}, destroy: () => {} @@ -106,7 +103,7 @@ requiredReturn; const optionalReturn: ActionReturn = { update: (p) => { p === true; - // @ts-expect-error could be undefined + // @ts-expect-error (only in strict mode) could be undefined p.toString(); } }; @@ -118,7 +115,7 @@ const invalidProperty: ActionReturn = { }; invalidProperty; -type Attributes = ActionReturn['$$_attributes']; +type Attributes = ActionReturn['$$_attributes']; const attributes: Attributes = { a: 'a' }; attributes; // @ts-expect-error wrong type