Svelte custom event on svelte typescript

10.4k views Asked by At

I'm using clickOutside directive on my svelte-typescript project and I'm getting this error when I assign custom event to the related element

Type '{ class: string; onclick_outside: () => boolean; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.
  Property 'onclick_outside' does not exist on type 'HTMLProps<HTMLDivElement>'

here's a snippet of my code

{#if profileToolbar}
<div
    transition:fly={{ y: -20, duration: 300 }}
    use:clickOutside={profileToolbarContainer}
    on:click_outside={() => (profileToolbar = !profileToolbar)}
    class="origin-top-right absolute right-0 mt-2 w-48 rounded-md
    shadow-lg z-10 shadow-md">

this is the clickOutside directive that I'm using currently https://svelte.dev/repl/0ace7a508bd843b798ae599940a91783?version=3.16.7

I'm new to typescript so I don't really know where to start with my google search, anyone knows how to tackle this issue? thanks for your help

6

There are 6 answers

1
oae On BEST ANSWER

Ok, so existing answers did work only partly for me. Given that the clickOutside action fires a custom event named click_outside i arrive at following solution:

declare namespace svelte.JSX {
    interface HTMLProps<T> {
        onclick_outside?: (e: CustomEvent) => void;
    }
}
6
hackape On

According to the doc, you can create a .d.ts file in your project somewhere. And put inside that file the following:

declare namespace svelte.JSX {
  interface HTMLAttributes<T> {
    onclick_outside: () => void
  }
}

Please read the doc for more detail.

2
Tomasz On

This declaration worked for me

declare namespace svelte.JSX {
  interface DOMAttributes<T> {
    onclick_outside?: CompositionEventHandler<T>;
  }
}

Don't forget to specify the location of your custom type declarations in tsconfig.json

0
Teiem On

For me the following worked:

declare namespace svelteHTML {
    interface HTMLAttributes<T> {
        "on:click_outside"?: CompositionEventHandler<T>;
    }
}

inside your src/app.d.ts.

based on this

2
Jonathan On

Update 7/23/23

New SvelteKit requires this:

Here is my src/app.d.ts file.

// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
    namespace App {
        // interface Error {}
        // interface Locals {}
        // interface PageData {}
        // interface Platform {}
    }

    declare namespace svelteHTML {
        interface HTMLAttributes<T> {
            'on:clickOutside'?: CompositionEventHandler<T>;
        }
    }
}

export { };

J

0
melMass On

You can now simply do

const dispatch = createEventDispatcher<{
    mounted: { id: string; store: FSStore }
    destroyed: { id: string }
  }>()

onMount(() => {
  dispatch('mounted', {
      id,
      store: fsStore,
  })
  return () => {
      dispatch('destroyed', {
        id,
      })
    }
})

This will then be fully typed:

<Explorer
  on:mounted={onExplorerMount}
  on:destroyed={onExplorerDestroy}
/>

ide preview