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
interface nor via an overload 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
submitter
, hence this need. I don't understand why I would be warned that submitter is already declared when I update the library. My temporary interface will be different from the updated library's. Even if they have the sameSubmitEvent
name, they would come from different files and the compiler will treat them independently. Could you explain this in more details? – Ocam