【问题标题】:How do you handle multiple types within same event emitter -Typescript你如何在同一个事件发射器中处理多种类型-Typescript
【发布时间】:2021-05-21 01:17:18
【问题描述】:

我正在尝试使用 typescript 创建一个函数,该函数检查“Enter”键是否按下,然后如果 event.target.value 的长度大于 0,则转到具有该值的页面。这是在 nextjs 应用程序中,因此是 router.push 行。代码大致如下:

const goToSearch = (e: React.KeyboardEvent<HTMLInputElement> | React.ChangeEvent<HTMLInputElement>) => {
    if (e.key === "Enter") {
      e.preventDefault();

      if (e.target.value.length > 0) {
        router.push(
          { pathname: "/Search", query: { searchVal: e.target.value } },
          "/Search"
        );
      }
    }
  };

为了触发这个功能,我在输入元素中使用了 onKeyDown 属性,像这样:

  <input
    type="search"
    className="form-control border border-white"
    placeholder="Search"
    aria-label="Search"
    onKeyDown={goToSearch}
  />

这里的挑战是因为我使用 typescript,e 类型可以是键盘事件或更改事件。如果我使用 |要提供这两种类型,我会收到错误,因为打字稿混淆了要引用的事件类型。有什么方法可以创建一个界面或一些利用这两种事件类型(键盘事件与更改事件)的自定义类型?此接口或自定义类型还需要考虑 preventDefault void 函数。

谢谢

【问题讨论】:

标签: typescript react-typescript


【解决方案1】:

在尝试访问联合类型中两种类型都不存在的属性之前,您可以使用类型保护来断言该事件是联合类型中的特定事件之一。

const goToSearch = (e: React.KeyboardEvent<HTMLInputElement> | 
React.ChangeEvent<HTMLInputElement>) => {
  const {key} = (e as React.KeyboardEvent<HTMLInputElement>)
  const {target} = (e as React.ChangeEvent<HTMLInputElement>)
  if (key === "Enter") {
    e.preventDefault();
  }
  if (target.value.length > 0) {
    // change route
  }
};

TS Playground


上面也可以写成

const goToSearch = (e: React.KeyboardEvent<HTMLInputElement> | React.ChangeEvent<HTMLInputElement>) => {
  if ((e as React.KeyboardEvent<HTMLInputElement>) && (e as React.KeyboardEvent<HTMLInputElement>).key === "Enter") {
    e.preventDefault();
  }

  if ((e as React.ChangeEvent<HTMLInputElement>) && (e as React.ChangeEvent<HTMLInputElement>).target.value.length > 0) {
    // change route
  }
};

User-Defined Type Guards

【讨论】:

  • 这行得通。你能解释一下你是如何得到这个解决方案的,只是为了我的理解。您从事件对象创建了两个解构变量,并将它们的类型专门设置为参数中规定的每种类型?既然它们是独立的并与特定的变量相关联,它们就避免了类型混淆?
  • 在得出这个答案之前,我阅读了关于这个问题的讨论。 stackoverflow.com/questions/44321326/…
  • 你的理解是正确的。 typescript 中的 as 字将变量断言为可能的类型之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-15
相关资源
最近更新 更多