6

I'm using Typescript inside my svelte project, I need to define strong type for my event. But I can't find any way to do that.

<script lang="ts">
  const onKeyUp = (event: [type here]) => {
    console.log({ event })
    // const {target, keyCode} = event
  }
</script>
<input type="text" on:keyup={onKeyUp} />

Anyone can help me!

aldenn
  • 2,060
  • 2
  • 11
  • 30
  • see also `React.MouseEvent` etc [here](https://stackoverflow.com/questions/42081549/typescript-react-event-types) and [here](https://stackoverflow.com/questions/44321326/property-value-does-not-exist-on-type-eventtarget-in-typescript) – milahu Oct 30 '22 at 17:27

2 Answers2

9

In your case you are looking for the KeyboardEvent type. If you additionally want to type your target, you need to cast it inside your function body. The reason is that it's not possible to statically know that the event handler is on the same element as the one that dispatched the event, so the typings err on the side of caution (see https://github.com/sveltejs/language-tools/issues/579 for more info). So the solution looks something like this:

<script lang="ts">
  const onKeyUp = (event: KeyboardEvent) => {
    // ...
    (event.target as HTMLInputElement)...;
  }
</script>
<input type="text" on:keyup={onKeyUp} />

What you can determine is the currentTarget, for which you can create your own helper type:

export type WithTarget<Event, Target> = Event & { currentTarget: Target };

usage:

<script lang="ts">
  import type { WithTarget } from './path/to/your/types/file.ts';
  const onKeyUp = (event: WithTarget<KeyboardEvent, HTMLInputElement>) => {
    // ...
  }
</script>
<input type="text" on:keyup={onKeyUp} />

In general, TypeScript comes with a standard lib of interfaces which define the possible DOM events, which are modelled after MDN's event description, like this one: https://developer.mozilla.org/de/docs/Web/API/KeyboardEvent

dummdidumm
  • 4,828
  • 15
  • 26
  • 1
    Seem to be it's wrong! Because the base `on:keyup` type of Svelte is `KeyboardEventHandler`. I received the typescript error like this: `Type '(event: WithTarget) => void' is not assignable to type 'KeyboardEventHandler'` – aldenn Nov 22 '21 at 04:11
  • 1
    You are right, I adjusted my post. – dummdidumm Nov 22 '21 at 09:56
  • This answer works perfectly. Thanks – aldenn Nov 24 '21 at 04:43
  • Almost works great for me, I have currently `({ target : { value } }: WithTarget ) => debounce(value)` and now defined it as a function `const onKeyUp = (event:WithTarget) => { const target = event.target const value = target?.value debounce(value) }` but it complains about `target.value` – SumNeuron Mar 10 '23 at 12:39
0

This is the only way I could do it:

const handleKey = (e: CustomEvent) => {

   const event = e as unknown as KeyboardEvent;
   
   if (event.key === 'Backspace') {
      ...
<TextField bind:value on:keyup={handleKey}>

I had to typecast.

J

Jonathan
  • 3,893
  • 5
  • 46
  • 77