Is there no SubmitEvent interface in Typescript?
Asked Answered
O

3

20

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.

Ocam answered 26/5, 2020 at 11:58 Comment(0)
G
13

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.

Ghoul answered 26/5, 2020 at 13:57 Comment(2)
I actually needed 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 same SubmitEvent name, they would come from different files and the compiler will treat them independently. Could you explain this in more details?Ocam
@VincentPazeller in TypeScript interfaces are open, so multiple declarations with the same name (and in the same common root) contribute to the same type. You should take advantage of this to extend the library interface, so you get told when it is updated (just in case the library version contains a subtle difference that is better than the version I've supplied).Ghoul
A
4

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

Anglofrench answered 29/8, 2021 at 4:18 Comment(0)
C
1

Safari doesn't seem to have implemented the SubmitEvent. That might be the reason why typescript has not created an interface for it. (I'm speculating.)

The only thing SubmitEvent is bringing to the table is submitter. That's the part that I was missing... I need Safari support, so I need to do a hack. Not just an interface-hack.

If someone has more info why it's not supported in Safari, please tell me.

References:

Concatenation answered 1/6, 2021 at 20:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.