【问题标题】:Is there no SubmitEvent interface in Typescript?Typescript中没有SubmitEvent接口吗?
【发布时间】:2020-09-13 05:23:44
【问题描述】:

TypeScript 有不同的接口来映射 DOM 事件。 (例如KeyboardEventMouseEvent 等)。我们可以找到他们here。 例如,当在事件侦听器中接收事件的有效负载时,它们在 Angular 中很方便。

我有点惊讶于无法找到SubmitEvent 的接口,描述为here

谁能确认并解释原因?我希望 TypeScript 团队为每个 DOM 事件共享接口。

【问题讨论】:

    标签: typescript dom-events typescript-lib-dom


    【解决方案1】:

    这些确实会随着时间的推移而增加。目前它在标准中被标记为“仅单一实现”,因此当它被更好地采用时更有可能被添加。 (我相信它现在在两个引擎中,所以标准将很快更新以反映这一点,我相信,它将在 Chromium 和 Gecko 中)。

    您可以在所有情况下使用Event,除非您确实需要使用较新的submitter,这是SubmitEvent 带来的唯一新增功能。

    如果您确实需要submitter,您可以轻松创建您的SubmitEvent 并调整HTMLFormElement 以使用它 - 如下所示。

    interface SubmitEvent extends Event {
      submitter: HTMLElement; 
    }
    
    interface HTMLFormElement {
      onsubmit: (this: GlobalEventHandlers, ev: SubmitEvent) => any | null;
    }
    

    更新库时,系统会警告您 submitter 已声明,您可以删除临时接口。

    【讨论】:

    • 我实际上需要submitter,因此需要。我不明白为什么在更新库时会警告我提交者已经声明。我的临时界面将与更新后的库不同。即使它们具有相同的SubmitEvent 名称,它们也会来自不同的文件,编译器将独立处理它们。你能详细解释一下吗?
    • @VincentPazeller 在 TypeScript 接口中是开放的,因此具有相同名称(并且在同一个公共根中)的多个声明有助于同一类型。您应该利用这一点来扩展库接口,以便在更新时得到通知(以防库版本包含比我提供的版本更好的细微差别)。
    【解决方案2】:

    Safari 似乎没有实现 SubmitEvent。这可能是 typescript 没有为其创建接口的原因。 (我在推测。)

    SubmitEvent 唯一带来的就是提交者。那是我缺少的部分... 我需要 Safari 支持,所以我需要做一个 hack。不仅仅是界面黑客。

    如果有人知道为什么 Safari 不支持它,请告诉我。

    参考资料:

    【讨论】:

      【解决方案3】:

      TypeScript 4.4some missing interfaces添加到标准定义库中,现在包含SubmitEvent接口,定义如下:

      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;
      }
      

      类型断言应该开箱即用,无需任何额外设置:

      {
          const form = document.querySelector<HTMLFormElement>("form");
          form?.addEventListener("submit", (event) => {
              const { submitter } = event as SubmitEvent;
              console.log(submitter?.id);
          });
      }
      

      Playground

      不幸的是,新接口既没有添加到 HTMLElementEventMap 也没有重载添加到 addEventListener 方法,因此如果您想要更无缝的体验,则必须使用声明合并(对于 onsubmit版本,见Fentonanswer):

      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

      【讨论】:

        猜你喜欢
        • 2021-12-07
        • 1970-01-01
        • 1970-01-01
        • 2021-12-09
        • 2019-04-03
        • 1970-01-01
        • 2017-04-17
        • 2023-02-21
        • 2016-07-18
        相关资源
        最近更新 更多