"EventTarget"类型中不存在属性"值"

use*_*018 69 typescript angular

我使用TypeScript版本2作为Angular 2组件代码.

我收到错误"属性'值'在类型'EventTarget'上不存在"下面的代码,可能是解决方案.谢谢!

e.target.value.match(/\S +/g)|| []).长度

import { Component, EventEmitter, Output } from '@angular/core';

@Component({
selector: 'text-editor',
template: `
<textarea (keyup)="emitWordCount($event)"></textarea>
 `
 })
  export class TextEditorComponent {
   @Output() countUpdate = new EventEmitter<number>();

emitWordCount(e: Event) {
    this.countUpdate.emit(
        (e.target.value.match(/\S+/g) || []).length);
}
}
Run Code Online (Sandbox Code Playgroud)

smn*_*brv 122

您需要明确告诉TypeScript您的目标HTMLElement的类型.

这样做的方法是使用泛型类型将其强制转换为正确的类型:

this.countUpdate.emit((<HTMLTextAreaElement>e.target).value./*...*/)
Run Code Online (Sandbox Code Playgroud)

或者(如你所愿)

this.countUpdate.emit((e.target as HTMLTextAreaElement).value./*...*/)
Run Code Online (Sandbox Code Playgroud)

或(再次,偏好问题)

const target = e.target as HTMLTextAreaElement;

this.countUpdate.emit(target.value./*...*/)
Run Code Online (Sandbox Code Playgroud)

这将让TypeScript知道元素是a textarea并且它将知道value属性.

任何类型的HTML元素都可以这样做,每当你给TypeScript更多关于它们的类型的信息时,它会给你带来适当的提示,当然还有更少的错误.

为了使将来更容易,您可能希望直接使用其目标类型定义事件:

// create a new type HTMLElementEvent that has a target of type you pass
// type T must be a HTMLElement (e.g. HTMLTextAreaElement extends HTMLElement)
type HTMLElementEvent<T extends HTMLElement> = Event & {
  target: T; 
  // probably you might want to add the currentTarget as well
  // currentTarget: T;
}

// use it instead of Event
let e: HTMLElementEvent<HTMLTextAreaElement>;

console.log(e.target.value);

// or in the context of the given example
emitWordCount(e: HTMLElementEvent<HTMLTextAreaElement>) {
  this.countUpdate.emit(e.target.value);
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么需要明确?这太浪费时间了,DOM 事件对我来说是使用 TS 的最大缺点之一,我总是在 SO 上寻找 TS 定义。 (12认同)

Jam*_*s D 88

对于那些在 Angular 13 中遇到此错误的人,因为从以前的版本升级

对我来说问题是我在 HTML 中使用了以下内容(之前是允许的)

(keyup)="applyFilter($event.target.value)" 
Run Code Online (Sandbox Code Playgroud)

解决这个问题的方法是:

HTML:

(keyup)="applyFilter($event)"
Run Code Online (Sandbox Code Playgroud)

组件 - 在我调用的函数中:

applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    // ... etc...
}

Run Code Online (Sandbox Code Playgroud)

现在我可以像以前一样再次使用filterValue。

  • 随着 Angular 变得越来越需要打字,这就是整个线程的答案。所有其他答案均为 N/A。使用控制器中的类型、目标和值发送“事件”工作。 (5认同)

Ste*_*ens 24

不要使用其他答案中涉及强制转换事件、事件目标或完全禁用类型检查的解决方法。这是不安全的。

相反,您应该从 HTML 元素中“提取”值并将其作为参数传递。

过于简单化的例子:

<input #searchBox type="text" (input)="doSearch(searchBox.value)">
Run Code Online (Sandbox Code Playgroud)
doSearch(text: string): void {
}
Run Code Online (Sandbox Code Playgroud)

因此,如果将其扩展到原始示例,您应该得到:

import { Component, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'text-editor',
  template: `
    <textarea #text (keyup)="emitWordCount(text.value)"></textarea>
  `
})
export class TextEditorComponent {
  @Output() countUpdate = new EventEmitter<number>();

  emitWordCount(text: string) {
    this.countUpdate.emit(
      (text.match(/\S+/g) || []).length);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @RaphaëlBalet 因为强制转换实际上告诉 TypeScript 编译器“不要对这行代码进行严格的类型检查”。强制转换对象只有程序员的类型检查,大脑是不可靠的。我提出的解决方案不依赖于强制转换或动态类型。 (6认同)
  • 优秀的解决方案 (3认同)
  • 这似乎是 Angular 现在推荐的方式:https://angular.io/guide/user-input#get-user-input-from-a-template-reference-variable (3认同)

Tor*_*hel 22

这是我使用的简单方法:

let element = event.currentTarget as HTMLInputElement;
let value = element.value;
Run Code Online (Sandbox Code Playgroud)

TypeScript编译器显示的错误消失了,代码也可以运行.

  • 如果您也使用复选框,这是一个很好的解决方案: const value = e.currentTarget.type === 'checkbox' ? (e.currentTarget as HTMLInputElement).checked : e.currentTarget.value (2认同)

bel*_*ref 20

由于我遇到了两个以稍微不同的方式搜索我的问题的问题,因此我将复制我的答案,以防您最终出现在这里。

在被调用的函数中,您可以使用以下命令定义您的类型:

emitWordCount(event: { target: HTMLInputElement }) {
  this.countUpdate.emit(event.target.value);
}
Run Code Online (Sandbox Code Playgroud)

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

event: Event & { target: HTMLInputElement }
Run Code Online (Sandbox Code Playgroud)

您还可以更具体,而不是使用HTMLInputElement您可以使用例如HTMLTextAreaElement用于 textareas。


7gu*_*uyo 18

角 10+

打开tsconfig.json和禁用strictDomEventTypes.

  "angularCompilerOptions": {
    ....
    ........
    "strictDomEventTypes": false
  }
Run Code Online (Sandbox Code Playgroud)

  • 禁用严格规则可能会导致编写不正确的代码,这不是一个很好的建议,尤其是随着 Angular 10+ 的进步。 (7认同)
  • 恐怕也不必显式转换类型,尤其是在如此小的/局部范围内。它给出了某种类型安全的外观,但实际上只与禁用严格检查一样好/坏。 (3认同)
  • 这个方法对我有用。强制转换在 html 中不起作用。这不起作用 `(keyup)="doFilter(($event.target as HTMLTextAreaElement).value)"` (3认同)

小智 9

考虑 $any()

<textarea (keyup)="emitWordCount($any($event))"></textarea>
Run Code Online (Sandbox Code Playgroud)

  • @Rahi.Shah 我在 Angular 12 上尝试过,它有效。如果您尝试访问嵌套属性,则需要将对象包裹在属性周围,例如“$any($event.target).value”,这会将“event.target”属性标记为“any”,然后您例如可以访问该值。 (6认同)

小智 8

fromEvent<KeyboardEvent>(document.querySelector('#searcha') as HTMLInputElement , 'keyup')
    .pipe(
      debounceTime(500),
      distinctUntilChanged(),
      map(e  => {
            return e.target['value']; // <-- target does not exist on {}
        })
    ).subscribe(k => console.log(k));
Run Code Online (Sandbox Code Playgroud)

也许像上面这样的东西会有所帮助。根据实际代码更改它。问题是........目标['价值']


Bur*_*baş 8

这是我使用的另一种简单方法;

    inputChange(event: KeyboardEvent) {      
    const target = event.target as HTMLTextAreaElement;
    var activeInput = target.id;
    }
Run Code Online (Sandbox Code Playgroud)


Rah*_*hah 8

角度 11+

打开tsconfig.json和禁用strictTemplates.

 "angularCompilerOptions": {
    ....
    ........
    "strictTemplates": false
  }
Run Code Online (Sandbox Code Playgroud)

  • 这可能会带来很多错误。不要这样做。至少,如果您赶时间,请在 tsconfig.json 中使用 "strictDomEventTypes": false 代替 (2认同)

C. *_*wis 7

就我而言,我有:

const handleOnChange = (e: ChangeEvent) => {
  doSomething(e.target.value);
}
Run Code Online (Sandbox Code Playgroud)

问题是我没有为 ChangeEvent 提供类型参数,因此它知道e.targetHTMLInputElement. 即使我手动告诉它这target是一个输入元素(例如const target: HTMLInputElement = e.target),它ChangeEvent仍然不知道这是有道理的。

解决方案是这样做:

// add type argument
const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
  doSomething(e.target.value);
}
Run Code Online (Sandbox Code Playgroud)

  • 问题是针对 Angular 的,而不是针对 React 的 (2认同)