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


112

我正在将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);
}
}

Answers:


185

您需要明确告诉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知道该元素是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);
}

@smnbbrv我而言是那么一个img文件位置显示IMG的基础上,SO 模板:<img [src]="url"> <br/> <input type='file' (change)="showImg($event)">组件:... this.url = event.target.result;有时工作有时不,当它不犯错是error TS2339: Property 'result' does not exist on type 'EventTarget'因为你的建议告诉TS更多关于它,在这个地方HTMLTextAreaElement我试着HTMLInputElementtarget.value没有更多的错误,但图像未显示。
Jeb50 '18

我惊讶地发现您无法将类型传递给该Event类型。您确实应该能够Event<HTMLInputElement>用作类型。
罗南

@RoRo事件具有以下相似的性质:targetcurrentTargetsrcElement; 一个将需要类型3泛型类型;即使他们使用默认类型(例如Event<T = any, C = any, S = any>,上面提到的类型),也比简单的as语句使用起来更不舒服。我也可以想象一下,对于第一个泛型而言可能是一场圣战:targetcurrentTarget。此外,许多库会滥用HTML事件,并且可能会将所需的任何内容放入上述属性中。可能这些就是为什么他们没有将其作为内置泛型的原因
smnbbrv

对于我的ion-searchbar,我正在使用(ionChangeEvent.target as HTMLIonInputElement).value as string
Cloud

39

这是我使用的简单方法:

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

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


5
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']


2

我认为它必须有效,但是我无法确定任何方法。其他方法可以是

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

2

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

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

2

由于我遇到了两个问题,它们以略有不同的方式搜索我的问题,因此我会复制我的答案,以防万一您落在这里。

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

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

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

event: Event & { target: HTMLInputElement }

您也可以更具体一些,HTMLInputElement例如可以代替HTMLTextAreaElementtextareas 来使用。


1

这是另一种指定方式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);
    }
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.