How to Fix "Property '...' does not exist on type 'EventTarget'" TypeScript Error?

Why Does This Happen?

This error happens because an event target has the EventTarget type, which does not have the property you're trying to access.

A common example of this is when TypeScript fails to recognize properties such as id, classList, etc. that you would normally expect to exist on a typical HTML element:

elem.addEventListener('click', function (e) {
  // Property 'id' does not exist on type 'EventTarget'.
  console.log(e.target.id);

  // Property 'classList' does not exist on type 'EventTarget'.
  console.log(e.target.classList);

  // ...
}, false);

The reason for this is that the EventTarget type does not inherit from the Element type — which is an intentional design choice because not all event targets necessarily represent HTML elements. Various entities, such as XMLHttpRequest, FileReader, AudioNode, AudioContext, etc. can also serve as event targets.

Since TypeScript does not assume that all event targets are HTML elements, it doesn't automatically recognize element-specific properties. This leads to the compiler error as it cannot verify the existence of properties like id, classList, and others on the EventTarget type.

How to Fix the Issue?

To fix this issue, you can assert the correct type of the event target to inform TypeScript about the expected properties. This can be achieved through type assertions, or type guards, allowing you to access the desired properties without compromising type safety:

  1. Type Assertion

    You can use the TypeScript as keyword to assert the correct type for the event target:

    elem.addEventListener('click', function (e) {
      const target = e.target as Element;
      console.log(target.id);
      console.log(target.classList);
      // ...
    }, false);
    

    You can also inline the type assertion and property accessor like so:

    elem.addEventListener('click', function (e) {
      console.log((e.target as Element).id);
      console.log((e.target as Element).classList);
      // ...
    }, false);
    
  2. Type Guard

    You can add a type guard using instanceof that explicitly checks if the element is an instance of the element type you expect. This helps TypeScript infer the correct types for the element:

    elem.addEventListener('click', function (e) {
      if (e.target instanceof Element) {
        console.log((e.target as Element).id);
        console.log((e.target as Element).classList);
        // ...
      }
    }, false);
    

    The instanceof check not only helps TypeScript infer the correct types but also provides a runtime check, ensuring that the code won't break if, for some reason, the event target is not an "Element".

Handling Specific Cases

In some cases, you may need to specify a more specific type, such as in the following case:

elem.addEventListener('click', function (e) {
  console.log((e.target as HTMLInputElement).value);
}, false);

elem.dispatchEvent(new Event('test'));

In the example, the event target is asserted as HTMLInputElement because the value property does not exist on the generic Element type. The HTMLInputElement type inherits from the Element type though. Therefore, it will have the generic element properties (such as id, classList, etc.) as well as the more specific ones that exclusively exist on the HTMLInputElement object (such as value, validity, etc.).

Below is a list of common errors associated with this issue, where specifying more specific types would resolve your issue:

You should choose the most appropriate type for the event target based on your specific use case. You can find the type for your HTML element in the list of Web API interfaces.


This post was published (and was last revised ) by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.