„Property 'value' does not exist on type 'EventTarget'“ – Wie man die Angst verliert und Ereignisse in TypeScript typisiert
\n\nHaben Sie jemals einen Event-Handler in TypeScript geschrieben, versucht event.target.value zu erhalten – und sofort eine rote Unterstreichung mit der Meldung bekommen: „Property 'value' does not exist on type 'EventTarget'“? Wenn ja, sind Sie nicht allein. Auf Stack Overflow hat diese Frage zehntausende Aufrufe gesammelt und sie quält weiterhin Anfänger und erfahrene Entwickler im Jahr 2025.
Das Problem ist nicht, dass TypeScript „böse“ oder „kaputt“ ist. Ganz im Gegenteil: Der Compiler schützt Sie vor dummen Fehlern, die zur Laufzeit auftreten könnten. Lassen Sie uns verstehen, warum dieser Fehler auftritt und wie man ihn richtig behebt.
\n\nWarum beschwert sich TypeScript über event.target.value?
\n\nKurze Antwort: event.target hat den Typ EventTarget | null. Und EventTarget hat keine Eigenschaft value. Es hat nur drei Methoden: addEventListener, removeEventListener und dispatchEvent.
Wenn Sie schreiben:
\n\nconst handleChange = (event: React.ChangeEvent) => {\n const value = event.target.value; // ❌ Fehler!\n};\n\n\nSieht TypeScript: „Hey, ich weiß nicht, welches konkrete HTML-Element dieses Ereignis ausgelöst hat. Vielleicht ist es ein <div>, das kein value hat, oder vielleicht ein <input> – ich bin mir nicht sicher. Daher weigere ich mich, solchen Code zu kompilieren.“
Das ist ein Feature, kein Bug. TypeScript zwingt Sie, explizit anzugeben, mit welchem Element Sie arbeiten.
\n\nTop-3 Lösungswege (aktuell für 2025)
\n\nEs gibt mehrere Ansätze. Wir betrachten die gängigsten und sichersten.
\n\n1. Cast mit as HTMLInputElement (schnell, aber vorsichtig)
\n\nDer gebräuchlichste Weg ist, event.target in den gewünschten Typ zu casten:
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const value = (event.target as HTMLInputElement).value;\n console.log(value);\n};\n\n\nVorteile: einfach, verständlich, funktioniert.
\nNachteile: Wenn Sie sich irren und das Ereignis tatsächlich von einem <textarea> oder <select> kommt, erhalten Sie zur Laufzeit undefined. Der Compiler warnt Sie nicht.
Verwenden Sie diese Methode am besten, wenn Sie absolut sicher über den Elementtyp sind. Zum Beispiel in einfachen Formularen mit einem einzigen Feld.
\n\n2. event.currentTarget statt event.target verwenden
\n\nIn TypeScript ist currentTarget strenger typisiert als target. Wenn Sie einen generischen Parameter für das Ereignis angeben, hat currentTarget den korrekten Typ:
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const value = event.currentTarget.value; // ✅ Funktioniert ohne Cast!\n};\n\n\nWichtig: currentTarget ist das Element, an das der Handler gebunden ist. Wenn Sie den Handler an ein <input> gebunden haben, ist currentTarget immer dieses <input>. Im Gegensatz zu target, das ein verschachteltes Element sein kann (z.B. ein <span> innerhalb eines Buttons).
Vorteile: Sicherer als ein Cast, keine zusätzlichen Typumwandlungen nötig.
\nNachteile: Nicht für alle Szenarien geeignet – z.B. bei Event-Bubbling kann currentTarget vom Zielelement abweichen.
3. Generische Funktion mit Überprüfung (der sicherste Weg)
\n\nWenn Sie maximale Sicherheit und Wiederverwendbarkeit wünschen, schreiben Sie eine Hilfsfunktion, die den Elementtyp überprüft:
\n\nfunction getInputValue(event: Event): string