Explain Codes LogoExplain Codes Logo

Property 'value' does not exist on type EventTarget in TypeScript

javascript
type-assertions
event-handling
typescript
Nikita BarsukovbyNikita Barsukov·Mar 3, 2025
TLDR

Overcome the infamous TypeScript error by typecasting event.target to HTMLInputElement while accessing the value property:

// Who you gonna call (for values)? Typecast! const value = (event.target as HTMLInputElement).value;

Taking a closer look at event targets

With DOM events in TypeScript, we need intimate knowledge of the trigger and its accessible properties. Here type assertions come to the rescue, like a well-timed superhero.

  • A trapdoor to escape EventTarget related issues - type assertions

Guarantees provided by TypeScript and event handling

Type safety is TypeScript's strong suit, making sure we aren't trying to access unknown properties from our objects. It's especially vital while wrestling with EventTarget in event handlers.

How to tread in different frameworks

Frameworks have their own behavior while handling events. In React, facilitate typing of events using React.ChangeEvent<HTMLInputElement>:

// Truth Bomb: React's got your 'event' back! const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { const value = event.target.value; };

Angular isn't left behind, allowing bypassing of strict checking with $any($event.target).value:

// Ssshh! Not-so-secret cheat code for Angular! <input (keyup)="$any($event.target).value" />

Always prefer safety over convenience while grounding your events. They are not your average teacup rides.

Shortest event path: Destructuring

Harness the power of JavaScript's modern syntax in your event handling. Destructuring can lead to cleaner, succinct code.

// Fancy a code snack? *serves destructured code* const handleChange = ({ target: { value } }: React.ChangeEvent<HTMLInputElement>) => { console.log(value); };

This practice is an open invitation to developers to consider the expected structure of the event target.

Ensuring compatibility with element types

The straight road to safety involves being explicit about the event type and properties access. Casting event.target to HTMLInputElement makes TypeScript happy (We all want that, right?).

Need values from dataset? We've got you!

Accessing custom data attributes (data-* attributes) requires you to dance with DOM elements a bit:

// Dataset dabbing!💃🕺 const key = (event.target as HTMLElement).dataset.key;

Casting to HTMLElement fits well here, providing broader support for dataset. Match your jigs with the HTML element type though!

Angular's flirting: Best practices and pitfalls

While Angular has its fun with events, ensure event.target matches your expected type:

// 'HTMLInputElement' casting - Angular way!😎 <input (input)="handleInput($event)" /> handleInput(event: Event): void { const value = (event.target as HTMLInputElement).value; }

Wrong casting could potentially summon run-time errors, if event.target is different. Check, double-check your damn casts!

TypeScript and runtime safety - A love story

TypeScript ensures safety at compile-time not at runtime. Therefore, we need type assertions when dealing with event listeners:

// Need a watchword for runtime safety? It's 'Type Assertion'! document.querySelector('input[type="text"]')?.addEventListener('change', (event) => { const value = (event.target as HTMLInputElement).value; });

Assert correct types, unlock happiness. As simple as that!