Die Eigenschaft 'value' ist für den Typ 'EventTarget' nicht vorhanden.

112

Ich verwende TypeScript Version 2 für einen Angular 2-Komponentencode.

Ich erhalte die Fehlermeldung "Eigenschaft 'Wert' existiert nicht für Typ 'EventTarget'" für den folgenden Code. Was könnte die Lösung sein? Vielen Dank!

e.target.value.match (/ \ S + / g) || []).Länge

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

Antworten:

184

Sie müssen TypeScript explizit den Typ des HTMLElement mitteilen, das Ihr Ziel ist.

Der Weg, dies zu tun, besteht darin, einen generischen Typ zu verwenden, um ihn in einen richtigen Typ umzuwandeln:

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

oder (wie du willst)

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

oder (wieder eine Frage der Präferenz)

const target = e.target as HTMLTextAreaElement;

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

Dadurch wird TypeScript darüber informiert, dass das Element a ist, textareaund es wird die value-Eigenschaft bekannt.

Dasselbe kann mit jeder Art von HTML-Element gemacht werden. Wenn Sie TypeScript ein bisschen mehr Informationen über ihre Typen geben, werden Sie mit den richtigen Hinweisen und natürlich weniger Fehlern zurückgezahlt.

Um es für die Zukunft einfacher zu machen, möchten Sie möglicherweise ein Ereignis direkt mit dem Typ seines Ziels definieren:

// 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
quelle
@smnbbrv Mein Fall ist ein Speicherort für eine IMG-Datei. Zeigen Sie dann die IMG an, basierend auf der SO- Vorlage: <img [src]="url"> <br/> <input type='file' (change)="showImg($event)">Komponente: ... this.url = event.target.result;Manchmal funktioniert es manchmal nicht, wenn es nicht fehlerhaft ist. error TS2339: Property 'result' does not exist on type 'EventTarget'Wie Sie vorgeschlagen haben, erzählen Sie TS mehr darüber, an der Stelle, an der HTMLTextAreaElementich es versucht habe, HTMLInputElementdann target.valuenicht mehr Fehler, aber das Bild wird nicht angezeigt.
Jeb50
Ich war überrascht zu sehen, dass Sie keinen Typ an den EventTyp übergeben konnten. Sie sollten wirklich in der Lage sein, Event<HTMLInputElement>als Typ zu verwenden.
Ronan
@RoRo Veranstaltung hat folgende ähnliche Objekte: target,currentTarget und srcElement; man müsste 3 generische Typen eingeben; Selbst wenn sie Standardtypen verwenden, z. B. Event<T = any, C = any, S = any>für die oben genannten, kann die Verwendung unangenehmer sein als die einfache asAnweisung. Ich könnte mir auch einen möglichen Holywar für das vorstellen, was zuerst generisch sein sollte: targetoder currentTarget. Darüber hinaus missbrauchen viele Bibliotheken HTML-Ereignisse und können möglicherweise alles, was sie wollen, in die genannten Eigenschaften einfügen. Wahrscheinlich sind dies die Gründe, warum sie es nicht als eingebaute Generika
getan haben
Für meine Ionensuchleiste verwende ich(ionChangeEvent.target as HTMLIonInputElement).value as string
Cloud
39

Hier ist der einfache Ansatz, den ich verwendet habe:

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

Der vom TypeScript-Compiler angezeigte Fehler ist verschwunden und der Code funktioniert.

Torsten Barthel
quelle
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));

Vielleicht könnte so etwas helfen. Ändern Sie es basierend auf dem realen Code. Das Problem ist ........ Ziel ['Wert']

Ahmed
quelle
2

Ich glaube, es muss funktionieren, aber ich kann mich nicht identifizieren. Ein anderer Ansatz kann sein:

<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);
       }
}
Mikronyken
quelle
2

Hier ist ein anderer einfacher Ansatz, den ich verwendet habe;

    inputChange(event: KeyboardEvent) {      
    const target = event.target as HTMLTextAreaElement;
    var activeInput = target.id;
    }
Burak Odabaş
quelle
2

Da ich zwei Fragen bei der Suche nach meinem Problem auf etwas andere Weise beantwortet habe, wiederhole ich meine Antwort, falls Sie hier landen.

In der aufgerufenen Funktion können Sie Ihren Typ definieren mit:

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

Dies setzt voraus, dass Sie nur an der targetImmobilie interessiert sind , was der häufigste Fall ist. Wenn Sie auf die anderen Eigenschaften von zugreifen müssen event, besteht eine umfassendere Lösung darin, den &Typschnittoperator zu verwenden:

event: Event & { target: HTMLInputElement }

Sie können auch spezifischer vorgehen und anstatt zu verwenden HTMLInputElement, können Sie zB HTMLTextAreaElementfür Textbereiche verwenden.

belvederef
quelle
1

Hier ist eine weitere Möglichkeit, Folgendes anzugeben 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);
    }
}

qiAlex
quelle