我只是想用我的KeyboardEvent做这个

var tag = evt.target.tagName.toLowerCase();

而事件。target是EventTarget类型,它不继承自Element。所以我必须像这样转换它:

var tag = (<Element>evt.target).tagName.toLowerCase();

这可能是因为一些浏览器不符合标准,对吧?TypeScript中正确的浏览器不可知实现是什么?

附注:我使用jQuery来捕获KeyboardEvent。


当前回答

使用typescript,我使用了一个只适用于我的函数的自定义接口。示例用例。

  handleChange(event: { target: HTMLInputElement; }) {
    this.setState({ value: event.target.value });
  }

在这种情况下,handleChange将接收一个目标字段为HTMLInputElement类型的对象。

在后面的代码中,我可以使用

<input type='text' value={this.state.value} onChange={this.handleChange} />

更清晰的方法是将接口放到一个单独的文件中。

interface HandleNameChangeInterface {
  target: HTMLInputElement;
}

然后使用下面的函数定义:

  handleChange(event: HandleNameChangeInterface) {
    this.setState({ value: event.target.value });
  }

在我的用例中,明确定义了handleChange的唯一调用者是输入文本的HTML元素类型。

其他回答

来自https://stackoverflow.com/a/48443771/5515861和https://stackoverflow.com/a/58806863/5515861的答案是正确的,但我有一个更好的方法来做。例如


  // in another file
  export interface DOMEvent<T extends EventTarget> extends Event {
  readonly target: T;
  }


  onFileChange(event: Event): void {
    const { target } = event as DOMEvent<HTMLInputElement>;
    if (target.files && target.files.length > 0) {
      // do something with the target
    }
  }

我用这个:

onClick({ target }: MouseEvent) => {
    const targetElement: HTMLElement = target as HTMLElement;
    
    const listFullHeight: number = targetElement.scrollHeight;
    const listVisibleHeight: number = targetElement.offsetHeight;
    const listTopScroll: number = targetElement.scrollTop;
    }

它不从Element继承,因为并非所有事件目标都是元素。

中数:

元素、文档和窗口是最常见的事件目标,但其他对象也可以是事件目标,例如XMLHttpRequest、AudioNode、AudioContext等。

甚至您尝试使用的KeyboardEvent也可以出现在DOM元素或窗口对象上(理论上也可以出现在其他东西上),所以在那里它对evt没有意义。目标定义为元素。

如果它是DOM元素上的一个事件,那么我想说您可以安全地假设event .target。是一个元素。我不认为这是跨浏览器行为的问题。只是EventTarget是一个比Element更抽象的接口。

进一步阅读:https://github.com/Microsoft/TypeScript/issues/29540

在处理来自输入字段的事件时,我通常会遇到这个问题,比如key up。但是请记住,事件可以起源于任何地方,例如文档上的keyup侦听器,其中没有关联的值。所以为了正确地提供信息,我提供了一个额外的类型:

interface KeyboardEventOnInputField extends KeyboardEvent {
  target: HTMLInputElement;
}
...

  onKeyUp(e: KeyboardEventOnInputField) {
    const inputValue = e.target.value;
    ...
  }

如果函数的输入类型是Event,你可能需要告诉typescript它实际上是什么:

  onKeyUp(e: Event) {
    const evt = e as KeyboardEventOnInputField;
    const inputValue = evt.target.value;
    this.inputValue.next(inputValue);
  }

例如,这在Angular中是必需的。

使用typescript,我使用了一个只适用于我的函数的自定义接口。示例用例。

  handleChange(event: { target: HTMLInputElement; }) {
    this.setState({ value: event.target.value });
  }

在这种情况下,handleChange将接收一个目标字段为HTMLInputElement类型的对象。

在后面的代码中,我可以使用

<input type='text' value={this.state.value} onChange={this.handleChange} />

更清晰的方法是将接口放到一个单独的文件中。

interface HandleNameChangeInterface {
  target: HTMLInputElement;
}

然后使用下面的函数定义:

  handleChange(event: HandleNameChangeInterface) {
    this.setState({ value: event.target.value });
  }

在我的用例中,明确定义了handleChange的唯一调用者是输入文本的HTML元素类型。