【问题标题】:Property 'value' does not exist on type EventTarget in TypeScriptTypeScript 中的 EventTarget 类型不存在属性“值”
【发布时间】:2017-11-03 09:59:30
【问题描述】:

所以下面的代码在 Angular 4 中,我不知道为什么它不能按预期工作。

这是我的处理程序的 sn-p:

onUpdatingServerName(event: Event) {
  console.log(event);
  this.newserverName = event.target.value; //this wont work
}

HTML 元素:

<input type="text" class="form-control" (input)="onUpdatingServerName($event)">

代码给了我错误:

“EventTarget”类型上不存在属性“值”。

但正如在console.log 中看到的那样,event.target 上确实存在该值。

【问题讨论】:

  • 我们可以使用 (e.target as HTMLInputElement).value
  • 兄弟,我为此苦苦挣扎了好几个小时,您只需从方法中删除类型。 onUpdatingServerName(event);

标签: javascript angular typescript


【解决方案1】:

event.target 这里是 HTMLElement,它是所有 HTML 元素的父元素,但不能保证具有 value 属性。 TypeScript 检测到这一点并抛出错误。将 event.target 转换为适当的 HTML 元素,以确保它是具有 value 属性的 HTMLInputElement

(<HTMLInputElement>event.target).value

the documentation:

输入 $event

上面的示例将$event 转换为any 类型。这以某种代价简化了代码。没有类型信息可以揭示事件对象的属性并防止愚蠢的错误。

[...]

$event 现在是特定的KeyboardEvent并非所有元素都有value 属性,因此它将target 强制转换为输入元素。

(强调我的)

【讨论】:

  • 语法更简洁var element = ev.target as HTMLElement
  • 对我来说,HTMLInputElement 代替了 HTMLElement,因为 HTMLElement 在界面中没有价值。
  • 在我看来,最好的方法是在被调用函数中使用onFieldUpdate(event: { target: HTMLInputElement }) {。请参阅下面的答案。
  • 对于 Angular 9,使用“as”语法。 event.target as HtmlInputlement
  • @Prescol 你有错字。这是event.target as HTMLInputElement
【解决方案2】:

将 HTMLInputElement 作为泛型传递给事件类型也应该有效:

onUpdatingServerName(event: React.ChangeEvent<HTMLInputElement>) {
  console.log(event);
  this.newserverName = event.target.value;
}

【讨论】:

  • 这比类型断言要好。
  • 如果函数是从 React 代码中的 onChange proeperty 处理程序引用调用的,这将不起作用。反应处理程序不希望为 React.ChangeEvent 设置类型,并将显示键入错误。我不得不改用所选答案(的变体),并使用演员:(event.target as HTMLInputElement).value.
  • 这在 React 组件中似乎对我很有效。也许是 React 的版本?我们目前在 16.8.*.
【解决方案3】:

这是另一个对我有用的修复:

(event.target as HTMLInputElement).value

应该通过让 TS 知道 event.target 是一个 HTMLInputElement 来消除错误,而 HTMLInputElement 本质上是一个 value。在指定之前,TS 可能只知道 event 单独是一个 HTMLInputElement,因此根据 TS,键入的 target 是一些随机映射的值,可以是任何东西。

【讨论】:

  • 这在 React 中非常有用,它试图将 解释为 JSX。
【解决方案4】:

我一直在寻找使用 React 的类似 TypeScript 错误的解决方案:

TypeScript 中的 EventTarget 类型上不存在属性“数据集”

我想在 React 中获得点击按钮元素的 event.target.dataset

<button
  onClick={onClickHandler}
  data-index="4"
  data-name="Foo Bar"
>
  Delete Candidate
</button>

这是我如何通过 TypeScript 使 dataset 值“存在”:

const onClickHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
  const { name, index } = (event.target as HTMLButtonElement).dataset
  console.log({ name, index })
  // do stuff with name and index…
}

【讨论】:

  • 问题被标记为 Angular,所以 React 的答案似乎离题了。
  • 无论如何......它有多个赞成票,因此这个答案对其他人有帮助。
  • 像魅力一样工作。 onChange={(event: ChangeEvent&lt;HTMLInputElement&gt;): void =&gt; { setTextFilter(event.target.value); }}
【解决方案5】:

我这样做的方式如下(比类型断言更好):

onFieldUpdate(event: { target: HTMLInputElement }) {
  this.$emit('onFieldUpdate', event.target.value);
}

这假设您只对target 属性感兴趣,这是最常见的情况。如果您需要访问event 的其他属性,更全面的解决方案是使用&amp; 类型的交集运算符:

event: Event & { target: HTMLInputElement }

这是一个 Vue.js 版本,但这个概念适用于所有框架。显然,您可以更具体,而不是使用一般的HTMLInputElement,您可以使用例如HTMLTextAreaElement 用于文本区域。

【讨论】:

    【解决方案6】:

    在模板中 -

    `(keyup)="value2=$any($event.target).value"`
    

    在组件中-

    getInput(event: Event) {
      this.value1 = (event.target as HTMLInputElement).value;
    }
    

    【讨论】:

    • 这是迄今为止最优雅的解决方案。
    【解决方案7】:

    如果你看不到,你应该使用 event.target.value 属性和 onChange 处理程序:

    index.js:1437 Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
    

    或者如果您想使用除 onChange 之外的其他处理程序,请使用 event.currentTarget.value

    【讨论】:

    • 这对我有用,但我不确定使用event.currentTarget.value 是最好的方法。
    【解决方案8】:

    您也可以创建自己的界面。

        export interface UserEvent {
          target: HTMLInputElement;
        }
    
           ...
    
        onUpdatingServerName(event: UserEvent) {
          .....
        }
    

    【讨论】:

      【解决方案9】:

      您可以将其显式解析为“HTMLInputElement”,然后访问“值”

      onUpdatingServerName(event: Event) {
        console.log(event);
        this.newserverName = (<HTMLInputElement>event.target).value; 
      }
      

      【讨论】:

        【解决方案10】:

        如您所知,TypeScript 一直严格地处理元素数据类型。因此,您不能在不指定数据类型的情况下直接访问元素的属性。 event.target 是一个 HTMLElement,它是所有 HTML 元素的父级,但不能保证具有 value 属性。

        所以,我们需要对变量event.target 进行类型转换,然后我们才能从中访问 value 属性。

        OnUpdatingServerName (event: Event) {
          console.log(event);
          var element = event.target as HTMLElement
          this.newserverName = element.value;
        }
        

        【讨论】:

          【解决方案11】:

          我建议创建一个实用程序类型:

          interface MyEvent<T extends EventTarget> extends Omit<Event, 'target'> {
            target: T;
          }
          

          然后像这样使用它:

          function onChange({ target: { value } }: MyEvent<HTMLInputElement>) => {
            doSomethingWith(value);
          }
          

          【讨论】:

            【解决方案12】:

            试试下面的代码:

              console.log(event['target'].value)
            

            它对我有用 :-)

            【讨论】:

            • 最好删除你的答案
            【解决方案13】:

            为事件添加任何类型

            event: any
            

            例子

            [element].addEvenListener('mousemove', (event: any) =>{
            //CODE//
            } )
            

            发生的情况是打字稿将“事件”(在本例中为单击)添加为事件类型,并且由于某种原因它无法识别某些属性。添加它的任何类型不再存在这个问题,这适用于任何document.[Property]

            【讨论】:

            • 欢迎您!为什么以及如何?请解释一下。
            • 如果你的答案几乎没有被减去,你可能会删除它
            • 添加any会在编译时发出警告,不建议在TS文件中使用any,否则使用ts文件的目的就没有了。
            • @ZeeshanSafdar 我同意你不应该做@dylanroman03 在这里所做的事情,但是any 在对象实际上可以是任何东西的情况下使用是完全可以的。一般来说,如果你知道对象的属性是什么(就像我们在这里所做的那样),你不应该使用any。如果对象可以有任何属性,你应该使用any
            猜你喜欢
            • 2018-08-15
            • 2017-06-23
            • 2019-08-18
            • 2021-05-18
            • 2021-06-03
            • 2021-05-27
            • 1970-01-01
            相关资源
            最近更新 更多