As @coldbreathe suggested in another answer, the most straightforward way seems to be annotating the handler function instead:
<script lang="ts">
import type { EventHandler } from "svelte/elements";
const handleSubmit: EventHandler<SubmitEvent, HTMLFormElement> =
function (event) {
const data = new FormData(event.currentTarget);
// event.currentTarget will have type HTMLFormElement here
};
</script>
<form on:submit|preventDefault={handleSubmit}>
<!-- ... -->
</form>
EventHandler<E, T>
here basically says that event
will have type E
and event.currentTarget
will have type T
. Here’s the actual definition:
type EventHandler<E extends Event = Event, T extends EventTarget = Element> = (
event: E & { currentTarget: EventTarget & T }
) => any;
currentTarget
and not just target
?EventHandler
annotation doesn’t doesn’t change type of event.target
– that’s because it could have bubbled from an element of any another type. It’s not something that should ever occur with SubmitEvent
in particular, but for other events it’s possible.
Rule of thumb: for consistency, just use currentTarget
, unless you need target
for some reason.