Skip to content

strictEvents event dispatchers can be called without providing a value when the event key is not optional #1966

@DetachHead

Description

@DetachHead

Describe the bug

if a key in an event dispatcher type is required, it can be dispatched without a value, causing the CustomEvent.detail to be null at runtime when typescript does not say it's nullable

Reproduction

a.svelte

<script lang="ts" strictEvents>
    import { createEventDispatcher } from 'svelte'

    const dispatch = createEventDispatcher<{ a: number }>()
</script>

<button on:click={() => dispatch('a')}>asdf</button>

b.svelte

<script lang="ts" strictEvents>
    import A from './a.svelte'
</script>

<A
    on:a={(e) => {
        // no typescript error, crashes at runtime
        console.log(e.detail.toString())
    }}
/>

Expected behaviour

the function created by createEventDispatcher should require the detail argument when the EventKey type is required.

the updated function signature could look something like this:

type RequiredKeys<T> = Exclude<{
    [K in keyof T]-?: undefined extends T[K] ? never : K;
}[keyof T], keyof {}>

type OptionalKeys<T> = Exclude<keyof T, RequiredKeys<T>>

declare function createEventDispatcher<EventMap extends {} = any>(): {
    <EventKey extends RequiredKeys<EventMap>>(type: EventKey, detail: EventMap[EventKey], options?: DispatchOptions): boolean;
    <EventKey extends OptionalKeys<EventMap>>(type: EventKey, detail?: EventMap[EventKey], options?: DispatchOptions): boolean;
}

playground

System Info

  • OS: windows 10
  • IDE: vscode

Which package is the issue about?

svelte-check

Additional Information, eg. Screenshots

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingupstream

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions