Skip to content

Commit

Permalink
fix: ensure createEventDispatcher works with types from generics
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
dummdidumm committed Jun 28, 2023
1 parent 1cfed0b commit 8c750da
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/long-humans-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: ensure createEventDispatcher works with types from generics
2 changes: 1 addition & 1 deletion documentation/docs/05-misc/03-typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
}>();
Expand Down
2 changes: 1 addition & 1 deletion documentation/docs/05-misc/04-v4-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{
optional: number | null;
required: string;
noArgument: never;
noArgument: null;
}>();

// Svelte version 3:
Expand Down
10 changes: 4 additions & 6 deletions packages/svelte/src/runtime/internal/public.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,12 @@ export interface DispatchOptions {
export interface EventDispatcher<EventMap extends Record<string, any>> {
// 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)
<Type extends keyof EventMap>(
...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;
}
2 changes: 1 addition & 1 deletion packages/svelte/test/types/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Action, ActionReturn } from '$runtime/action';
import type { Action, ActionReturn } from '$runtime/action/public';

// ---------------- Action

Expand Down
2 changes: 1 addition & 1 deletion packages/svelte/test/types/create-event-dispatcher.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createEventDispatcher } from '$runtime/internal/lifecycle';

const dispatch = createEventDispatcher<{
loaded: never;
loaded: null;
change: string;
valid: boolean;
optional: number | null;
Expand Down

0 comments on commit 8c750da

Please sign in to comment.