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`
pull/8872/head
Simon Holthausen 3 years ago
parent 1cfed0bf29
commit 8c750dadb8

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure createEventDispatcher works with types from generics

@ -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
}>();

@ -36,7 +36,7 @@ import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{
optional: number | null;
required: string;
noArgument: never;
noArgument: null;
}>();
// Svelte version 3:

@ -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;
}

@ -1,4 +1,4 @@
import type { Action, ActionReturn } from '$runtime/action';
import type { Action, ActionReturn } from '$runtime/action/public';
// ---------------- Action

@ -1,7 +1,7 @@
import { createEventDispatcher } from '$runtime/internal/lifecycle';
const dispatch = createEventDispatcher<{
loaded: never;
loaded: null;
change: string;
valid: boolean;
optional: number | null;

Loading…
Cancel
Save