baitendbidz
baitendbidz

Reputation: 893

Does Svelte provide a TypeScript type for input change events?

Given the following sample code for a file input

<script lang="ts">
function onFileSelected(event) {
    const file: File = event.target.files[0];

    // ...
}
</script>

<input type="file" on:change={onFileSelected} />

I would like to add a type to the parameter event ( instead of any ). I tried Event and InputEvent but both don't know about the files field.

I'm looking for something like Svelte.ChangeEvent<HTMLFileInputElement>. Is there something I could use?

Upvotes: 2

Views: 2048

Answers (2)

LEMUEL  ADANE
LEMUEL ADANE

Reputation: 8818

Do this:

<script lang="ts">
  function onFileSelected(event: Event) {
    const target = event.target as unknown as { files: File[] };
    const file: File = target?.files[0];
  }
</script>      
<main>
  <input type="file" on:change={onFileSelected} />
</main>

And the red squeegee lines will go away.

Upvotes: 1

brunnerh
brunnerh

Reputation: 184386

Svelte has internal types, but it might not be the best idea to use them as they could change. They type the handler as a whole, which could be done like this for example:

const onFileSelected: svelte.JSX.EventHandler<Event, HTMLInputElement> = e => {
    if (e.currentTarget.files == null)
        return; // files can be null, handle however appropriate

    const file = e.currentTarget.files[0];
};

(The types do not affect target, which in many cases cannot be typed definitively. E.g. for a click event it can be any descendant of the element with the handler. Use currentTarget instead.)

You can also just do something similar yourself:

function onFileSelected(e: Event & { currentTarget: HTMLInputElement }) {
  // ...
}

This could then also be extracted to a generic type alias:

type ElementEvent<T extends Element> = Event & { currentTarget: T }

(Event could also be made a parameter, in case a more specific event is used.)

Upvotes: 4

Related Questions