From 8c750dadb8f063daf077187fc760322555762139 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 28 Jun 2023 16:50:08 +0200 Subject: [PATCH] fix: ensure createEventDispatcher works with types from generics fixes #8860 This contains a small but unfortunately unavoidable breaking change: If you used `never` to type that the second parameter shouldn't be set (which the docs recommended for a short time), then you need to change that to `null` --- .changeset/long-humans-dress.md | 5 +++++ documentation/docs/05-misc/03-typescript.md | 2 +- documentation/docs/05-misc/04-v4-migration-guide.md | 2 +- packages/svelte/src/runtime/internal/public.d.ts | 10 ++++------ packages/svelte/test/types/actions.ts | 2 +- packages/svelte/test/types/create-event-dispatcher.ts | 2 +- 6 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 .changeset/long-humans-dress.md diff --git a/.changeset/long-humans-dress.md b/.changeset/long-humans-dress.md new file mode 100644 index 000000000000..68502950f72e --- /dev/null +++ b/.changeset/long-humans-dress.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure createEventDispatcher works with types from generics diff --git a/documentation/docs/05-misc/03-typescript.md b/documentation/docs/05-misc/03-typescript.md index 36378365fd50..778e13ce37f4 100644 --- a/documentation/docs/05-misc/03-typescript.md +++ b/documentation/docs/05-misc/03-typescript.md @@ -96,7 +96,7 @@ Events can be typed with `createEventDispatcher`: import { createEventDispatcher } from 'svelte'; const dispatch = createEventDispatcher<{ - event: never; // does not accept a payload + event: null; // does not accept a payload type: string; // has a required string payload click: string | null; // has an optional string payload }>(); diff --git a/documentation/docs/05-misc/04-v4-migration-guide.md b/documentation/docs/05-misc/04-v4-migration-guide.md index 25faea67cead..81749a4ba969 100644 --- a/documentation/docs/05-misc/04-v4-migration-guide.md +++ b/documentation/docs/05-misc/04-v4-migration-guide.md @@ -36,7 +36,7 @@ import { createEventDispatcher } from 'svelte'; const dispatch = createEventDispatcher<{ optional: number | null; required: string; - noArgument: never; + noArgument: null; }>(); // Svelte version 3: diff --git a/packages/svelte/src/runtime/internal/public.d.ts b/packages/svelte/src/runtime/internal/public.d.ts index 6eab766077b6..1f1011740d21 100644 --- a/packages/svelte/src/runtime/internal/public.d.ts +++ b/packages/svelte/src/runtime/internal/public.d.ts @@ -80,14 +80,12 @@ export interface DispatchOptions { export interface EventDispatcher> { // 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 + // - | null | undefined is added for convenience, as they are equivalent for the custom event constructor (both result in a null detail) ( - ...args: [EventMap[Type]] extends [never] - ? [type: Type, parameter?: null | undefined, options?: DispatchOptions] - : null extends EventMap[Type] - ? [type: Type, parameter?: EventMap[Type], options?: DispatchOptions] + ...args: null extends EventMap[Type] + ? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions] : undefined extends EventMap[Type] - ? [type: Type, parameter?: EventMap[Type], options?: DispatchOptions] + ? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions] : [type: Type, parameter: EventMap[Type], options?: DispatchOptions] ): boolean; } diff --git a/packages/svelte/test/types/actions.ts b/packages/svelte/test/types/actions.ts index bc1225a8ca20..03659e760540 100644 --- a/packages/svelte/test/types/actions.ts +++ b/packages/svelte/test/types/actions.ts @@ -1,4 +1,4 @@ -import type { Action, ActionReturn } from '$runtime/action'; +import type { Action, ActionReturn } from '$runtime/action/public'; // ---------------- Action diff --git a/packages/svelte/test/types/create-event-dispatcher.ts b/packages/svelte/test/types/create-event-dispatcher.ts index 31f06f71b56c..f85196930b58 100644 --- a/packages/svelte/test/types/create-event-dispatcher.ts +++ b/packages/svelte/test/types/create-event-dispatcher.ts @@ -1,7 +1,7 @@ import { createEventDispatcher } from '$runtime/internal/lifecycle'; const dispatch = createEventDispatcher<{ - loaded: never; + loaded: null; change: string; valid: boolean; optional: number | null;