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

116

Der folgende Code befindet sich also in Angular 4 und ich kann nicht herausfinden, warum er nicht wie erwartet funktioniert.

Hier ist ein Ausschnitt meines Handlers:

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

HTML-Element:

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

Der Code gibt mir den Fehler:

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

Aber wie man an dem sehen kann, console.logexistiert dieser Wert auf dem event.target.

Ravy
quelle
2
wir können (e.target als HTMLInputElement) .value
user1162084

Antworten:

145

event.targetHier ist ein HTMLElementElement, das das übergeordnete Element aller HTML-Elemente ist, dessen Eigenschaft jedoch nicht garantiert ist value. TypeScript erkennt dies und löst den Fehler aus. In event.targetdas entsprechende HTML-Element umwandeln, um sicherzustellen, dass es HTMLInputElementeine valueEigenschaft hat:

(<HTMLInputElement>event.target).value

Gemäß der Dokumentation :

Schreib die $event

Im obigen Beispiel wird das $eventals anyTyp verwendet. Das vereinfacht den Code auf Kosten. Es gibt keine Typinformationen, die Eigenschaften des Ereignisobjekts aufdecken und dumme Fehler verhindern könnten.

[...]

Das $eventist jetzt eine spezifische KeyboardEvent. Nicht alle Elemente haben eine valueEigenschaft, daher wird sie targetin ein Eingabeelement umgewandelt.

(Hervorhebung von mir)

Andrew Li
quelle
26
Etwas sauberere Syntaxvar element = ev.target as HTMLElement
Adrian Moisa
Für mich funktionierte HTMLInputElement anstelle von HTMLElement, da HTMLElement keinen Wert in der Schnittstelle hat.
Harsha Vardhini
Der beste Ansatz ist meiner Meinung onFieldUpdate(event: { target: HTMLInputElement }) {nach die aufgerufene Funktion. Siehe meine Antwort unten.
Belvederef
Verwenden Sie für Angular 9 die Syntax "as". event.target as HtmlInputlement
Prescol
86

Das Übergeben von HTMLInputElement als Generikum an den Ereignistyp sollte ebenfalls funktionieren:

onUpdatingServerName(event: React.ChangeEvent<HTMLInputElement>) {
  console.log(event);
  this.newserverName = event.target.value;
}
Mikael Lirbank
quelle
14
Dies ist besser als Typzusicherungen.
JamesYin
2
Dies funktioniert jedoch nicht, wenn die Funktion von einer onChangeReferenz für den Immobilienhandler im React-Code aufgerufen wird . Der React-Handler erwartet nicht, dass der Typ für das React.ChangeEvent festgelegt wird, und zeigt einen Tippfehler an. Ich musste stattdessen auf (eine Variante von) der ausgewählten Antwort mit einer Besetzung zurückgreifen : (event.target as HTMLInputElement).value.
Spiralis
Dies schien für mich in einer React-Komponente gut zu funktionieren. Vielleicht ist es die Version von React? Wir sind derzeit am 16.8. *.
Hellatan
49

Hier ist ein weiterer Fix, der für mich funktioniert:

(event.target as HTMLInputElement).value

Das sollte den Fehler beseitigen, indem TS wissen lässt, dass event.targetes sich um eine handelt HTMLInputElement, die von Natur aus eine hat value. Vor der Angabe wusste TS wahrscheinlich nur, dass dies eventallein ein Wert war. HTMLInputElementLaut TS handelte es sich bei dem eingegebenen targetWert also um einen zufällig zugeordneten Wert, der alles sein konnte.

Matt S.
quelle
4
Dies war in React sehr hilfreich, wo versucht wurde, <HTMLInputElement> als JSX zu interpretieren.
Christopher Bradshaw
Hey Mann, danke fürs Teilen! Diese Lösung passt zu mir.
Carlos Querioz
16

Ich suchte nach einer Lösung für einen ähnlichen TypeScript-Fehler mit React:

Die Eigenschaft 'Dataset' ist für den Typ EventTarget in TypeScript nicht vorhanden

Ich wollte zu event.target.dataseteinem angeklickten Schaltflächenelement in React gelangen:

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

So konnte ich den datasetWert über TypeScript auf "existieren" bringen:

const onClickHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
  const { name, index } = (event.target as HTMLButtonElement).dataset
  console.log({ name, index })
  // do stuff with name and index…
}
Beau Smith
quelle
1
Die Frage ist als "Angular" gekennzeichnet, sodass eine Antwort "Reagieren" nicht zum Thema gehört.
John Snow
2
Unabhängig davon… es hat mehrere Stimmen, daher war diese Antwort für andere hilfreich.
Beau Smith
1
Klappt wunderbar. onChange={(event: ChangeEvent<HTMLInputElement>): void => { setTextFilter(event.target.value); }}
Vadorequest
2

Sie sollten event.target.valueprop mit onChange-Handler verwenden, wenn Sie nicht sehen können:

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`.

Oder Wenn Sie einen anderen Handler als onChange verwenden möchten, verwenden Sie event.currentTarget.value

JillAndMe
quelle
Das funktioniert bei mir, aber ich bin mir nicht sicher, ob event.currentTarget.valuees der beste Ansatz ist.
dczii
2

Die Art und Weise, wie ich es mache, ist die folgende (besser als Typ Assertion imho):

onFieldUpdate(event: { target: HTMLInputElement }) {
  this.$emit('onFieldUpdate', 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 }

Dies ist eine Vue.js-Version, aber das Konzept gilt für alle Frameworks. Natürlich können Sie spezifischer vorgehen und anstelle eines allgemeinen HTMLInputElementzB HTMLTextAreaElementfür Textbereiche verwenden.

belvederef
quelle