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

Posted

技术标签:

【中文标题】“EventTarget”类型上不存在属性“值”【英文标题】:Property 'value' does not exist on type 'EventTarget' 【发布时间】:2017-06-23 07:32:35 【问题描述】:

我将 TypeScript 版本 2 用于 Angular 2 组件代码。

对于下面的代码,我收到错误“'EventTarget' 类型上不存在属性'值'”,可能是什么解决方案。谢谢!

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

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

【问题讨论】:

这能回答你的问题吗? The property 'value' does not exist on value of type 'htmlElement' tektutorialshub.com/angular/… 我想这会回答这个问题 【参考方案1】:

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

做到这一点的方法是使用泛型类型将其转换为适当的类型:

this.countUpdate.emit((<HTMLTextAreaElement>e.target).value./*...*/)

或(如你所愿)

this.countUpdate.emit((e.target as HTMLTextAreaElement).value./*...*/)

或(再次,偏好问题)

const target = e.target as HTMLTextAreaElement;

this.countUpdate.emit(target.value./*...*/)

这会让 TypeScript 知道该元素是 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);

【讨论】:

@smnbbrv 我的情况是一个img文件位置然后显示img,基于SO模板:&lt;img [src]="url"&gt; &lt;br/&gt; &lt;input type='file' (change)="showImg($event)"&gt;组件:... this.url = event.target.result;有时工作有时不,当它不是错误时@ 987654329@ 正如你所建议的,告诉 TS 更多信息,在HTMLTextAreaElement 的地方我尝试了HTMLInputElement 然后target.value 没有更多错误但图像不显示。 我很惊讶地发现您无法将类型传递给 Event 类型。你应该真的可以使用Event&lt;HTMLInputElement&gt; 作为类型。 @RoRo 事件具有以下类似属性:targetcurrentTargetsrcElement;需要输入 3 个泛型类型;即使他们使用默认类型,例如对于上面提到的Event&lt;T = any, C = any, S = any&gt;,使用起来可能比简单的as 语句更不舒服。我还可以想象一场潜在的圣战,首先应该是通用的:targetcurrentTarget。此外,许多库滥用 HTML 事件,并可能将他们想要的任何内容放在提到的属性中。可能这就是他们没有将其作为内置泛型做的原因 对于我的离子搜索栏,我使用的是(ionChangeEvent.target as HTMLIonInputElement).value as string 为什么需要显式?这太浪费时间了,DOM 事件是我使用 TS 的最大缺点之一,我一直在寻找 SO 上的 TS 定义。【参考方案2】:

这是我使用的简单方法:

const element = event.currentTarget as HTMLInputElement
const value = element.value

TypeScript 编译器显示的错误消失了,代码可以工作了。

【讨论】:

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

Angular 10+

打开tsconfig.json 并禁用strictDomEventTypes

  "angularCompilerOptions": 
    ....
    ........
    "strictDomEventTypes": false
  

【讨论】:

禁用严格的规则可能允许编写不正确的代码,这不是一个很好的建议,尤其是随着 Angular 10+ 的进步。 恐怕不必显式地强制转换类型,尤其是在如此小的/本地范围内。它给人以某种类型安全的外观,但实际上只有禁用严格检查的好/坏。 这个方法对我有用。投射在 html 中不起作用。这不起作用(keyup)="doFilter(($event.target as HTMLTextAreaElement).value)"【参考方案4】:

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

在被调用的函数中,你可以定义你的类型:

emitWordCount(event:  target: HTMLInputElement ) 
  this.countUpdate.emit(event.target.value);

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

event: Event &  target: HTMLInputElement 

您也可以更具体,而不是使用HTMLInputElement,您可以使用例如HTMLTextAreaElement 用于文本区域。

【讨论】:

【参考方案5】:

就我而言,我有:

const handleOnChange = (e: ChangeEvent) => 
  doSomething(e.target.value);

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

解决办法是:

// add type argument
const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => 
  doSomething(e.target.value);

【讨论】:

【参考方案6】:

考虑 $any()

<textarea (keyup)="emitWordCount($any($event))"></textarea>

【讨论】:

所有此解决方案不适用于 Angular 10+,因此请指定 Angular 版本。 @Rahi.Shah 我在 Angular 12 上尝试过它并且它有效。如果您尝试访问嵌套属性,则需要将对象包装在该属性周围,例如$any($event.target).value,这会将event.target 属性标记为any,例如,您可以访问该值。【参考方案7】:

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

    inputChange(event: KeyboardEvent)       
    const target = event.target as HTMLTextAreaElement;
    var activeInput = target.id;
    

【讨论】:

【参考方案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));

也许像上面这样的东西会有所帮助。 根据真实代码进行更改。 问题是........ target['value']

【讨论】:

【参考方案9】:

Angular 11+

打开tsconfig.json并禁用strictTemplates

 "angularCompilerOptions": 
    ....
    ........
    "strictTemplates": false
  

【讨论】:

工作 Angular 11【参考方案10】:

最好的方法是使用模板 => 将 id 添加到您的输入中,然后使用它的值

searchNotary(value: string) 
 // your logic

这样在激活严格验证时您将永远不会出现 Typescript 错误 => 请参阅 Angular 文档

【讨论】:

【参考方案11】:

我相信它必须有效,但我无法识别任何方式。 其他方法可以,

<textarea (keyup)="emitWordCount(myModel)" [(ngModel)]="myModel"></textarea>


export class TextEditorComponent 
   @Output() countUpdate = new EventEmitter<number>();

   emitWordCount(model) 
       this.countUpdate.emit(
         (model.match(/\S+/g) || []).length);
       

【讨论】:

【参考方案12】:

User TypeScript 内置实用程序类型Partial&lt;Type&gt;

在您的模板中

(keyup)="emitWordCount($event.target)"

在你的组件中

 emitWordCount(target: Partial<HTMLTextAreaElement>) 
    this.countUpdate.emit(target.value./*...*/);
  

【讨论】:

非常感谢,工作就像一个魅力。对于 Angular 用户,使用它并且不要忘记启用 "strictDomEventTypes": true。还使用Partial&lt;HTMLInputElement&gt; 进行输入【参考方案13】:

这里是另一种指定event.target的方法:

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( target =  as HTMLTextAreaElement )  // <- right there

        this.countUpdate.emit(
          // using it directly without `event`
            (target.value.match(/\S+/g) || []).length);
    

【讨论】:

【参考方案14】:

请改用currentValue,因为currentValue 的类型是EventTarget &amp; HTMLInputElement

【讨论】:

以上是关于“EventTarget”类型上不存在属性“值”的主要内容,如果未能解决你的问题,请参考以下文章

TS2339:“EventTarget”类型上不存在“最近”属性。 - 如何在 React 中获取原生 event.target?

TypeScript 中的 EventTarget 类型不存在属性“值”

“ObjectConstructor”类型上不存在属性“值”

TypeScript - 类型上不存在属性(但存在)?

“从不”类型上不存在属性“值”。在 mui 中使用 useRef 挂钩时

Angular 2 属性在类型上不存在