TypeScript has different interfaces mapping DOM events. (e.g. KeyboardEvent
, MouseEvent
, etc.). We can find them here.
For instance, they are handy in Angular when receiving an event's payload in an event listener.
I have been a bit surprised to be unable to find an interface for the SubmitEvent
which is described here.
Can anyone confirm and explain why? I would expect the TypeScript team to share interfaces for every DOM event.
TypeScript infers the type of the e parameter in handleChange to be any . So, no type checking will occur when e is referenced in the handler implementation. Not good! So, the type is ChangeEvent<HTMLInputElement> .
Events supported are: AnimationEvent , ChangeEvent , ClipboardEvent , CompositionEvent , DragEvent , FocusEvent , FormEvent , KeyboardEvent , MouseEvent , PointerEvent , TouchEvent , TransitionEvent , WheelEvent .
The submit event fires when the user clicks a submit button ( <button> or <input type="submit">) or presses Enter while editing a field (e.g. <input type="text">) in a form. The event is not sent to the form when calling the form. submit() method directly.
These do tend to get added over time. At the moment it is marked in the standard as "single implementation only", so it is more likely to be added when it has better adoption. (I believe it is in two engines now, so the standard will be updated to reflect that soon, I believe, as it will be in Chromium and Gecko).
You can use Event
in all cases, unless you actually need to use the newer submitter
, which is the only addition the SubmitEvent
brings to the table.
If you do need submitter
, you can easily create your SubmitEvent
and adjust the HTMLFormElement
to use it - as shown below.
interface SubmitEvent extends Event {
submitter: HTMLElement;
}
interface HTMLFormElement {
onsubmit: (this: GlobalEventHandlers, ev: SubmitEvent) => any | null;
}
When the library is updated, you'll be warned that submitter
is already declared and you can delete your temporary interface.
TypeScript 4.4 added some missing interfaces to the standard definitions library, which now includes SubmitEvent
interface defined as follows:
interface SubmitEvent extends Event {
/**
* Returns the element representing the submit button that triggered the form submission, or null if the submission was not triggered by a button.
*/
readonly submitter: HTMLElement | null;
}
A type assertion should work out-of-the-box without any extra setup:
{
const form = document.querySelector<HTMLFormElement>("form");
form?.addEventListener("submit", (event) => {
const { submitter } = event as SubmitEvent;
console.log(submitter?.id);
});
}
Playground
Unfortunately, the new interface is not added neither to the HTMLElementEventMap
nor an overload is added to the addEventListener
method, so you will have to utilize declaration merging if you want a more seamless experience (for the onsubmit
version, see Fenton's answer):
interface HTMLFormElement {
addEventListener(type: "submit", listener: (this: HTMLFormElement, ev: SubmitEvent) => any, options?: boolean | AddEventListenerOptions): void;
}
{
const form = document.querySelector<HTMLFormElement>("form");
form?.addEventListener("submit", ({ submitter }) => {
console.log(submitter?.id);
});
}
Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With