Reputation: 163
I am trying to build a simple form in Svelte TypeScript.
My on:submit looks like this: <form on:submit={onSubmit}>
, and my onSubmit function is defined as:
const onSubmit = (event: HTMLFormElement) => {
event.preventDefault();
dispatch("addPerson", person);
person = {
name: "",
isOwed: 0,
};
};
With this code I get the TypeScript problem:
Type '(event: HTMLFormElement) => void' is not assignable to type 'EventHandler<Event, HTMLFormElement>'. Types of parameters 'event' and 'event' are incompatible.
I get that the event passed to onSubmit has the type EventHandler<Event, HTMLFormElement>
, and that my function is only expecting HTMLFormElement, but I can't manage to expect the whole EventHandler object. How can I achieve this?
Upvotes: 9
Views: 8226
Reputation: 2022
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.
Upvotes: 0
Reputation: 91
Try this instead.
<script lang="ts">
const handleSubmit: svelte.JSX.EventHandler<Event, HTMLFormElement> = () => {
}
</script>
<form on:submit|preventDefault={handleSubmit}>
</form>
Upvotes: 4
Reputation: 4161
The event type is a SubmitEvent
.
function handleSubmit(e: SubmitEvent) {
const formData = new FormData(e.target as HTMLFormElement)
}
<form on:submit|preventDefault={handleSubmit}>
Upvotes: 13
Reputation: 14873
The event
parameter is an Event
, not a HTMLFormElement
HTML node. So you can replace event: HTMLFormElement
to event: Event
or even better (as suggested by TypeScript): event: EventHandler<Event, HTMLFormElement>
.
Upvotes: 1