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

Let's suppose we have the following HTML element:

<div id="foo"></div>

With the following code snippet we will receive the element above as an event target in our event listener:

const elem = document.getElementById('foo');

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

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

This code runs perfectly fine because we know we're expecting the event target to be an HTML element, and we are certain that the HTML element has the property id. However, TypeScript complains about the id property not existing on the EventTarget type. This is because:

  • By default an event target element has an EventTarget type in TypeScript;
  • The EventTarget type does not inherit from the Element type which is why TypeScript fails to recognize properties such as id, class, etc. that we would expect to exist on a typical Element object.

Why Does the EventTarget Type Not Inherit From Element Type?

The reason this is the case is simply because all event targets might not be HTML elements. For example the event target can be also be XMLHttpRequest, FileReader, AudioNode, AudioContext, etc.

How to Fix This Error?

To make TypeScript understand the correct type for the event target, we can specify it like so:

const elem = document.getElementById('foo');

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

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

We can also inline it like so:

(e.target as Element).id

Alternatively, we can also do the following if we only need to use the target property from the event:

const elem = document.getElementById('foo');

elem.addEventListener('test', function (e: { target: Element }) {
    console.log(e.target.id); // 'foo'

    // Property 'type' does not exist on type '{ target: HTMLInputElement; }'.
    console.log(e.type);
}, false);

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

As it is evident from the example above, after specifying the correct type for e.target it works fine. However, other properties (such as e.type, etc.) would throw a TypeScript error. If we need to access those other properties of the event as well, we could do so in the following way:

const elem = document.getElementById('foo');

elem.addEventListener('test', function (e: Event & { target: Element }) {
    console.log(e.target.id); // 'foo'

    // other Event object properties are recognized too now:
    console.log(e.type); // 'test'
}, false);

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

We can, of course, get more specific with the type of the target events. For example, let's suppose we wanted to get the value attribute of the following target input element:

<input id="foo" type="text" value="bar" />

Without setting the proper type for the event target, we'll get the "Property 'value' does not exist on type 'EventTarget'" error while trying to get the value property of the input element. Therefore, as discussed earlier, we need to assert the type we expect the event target to be like in the following way for example:

const elem = document.getElementById('foo');

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

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

In the code above we used a more specific type (i.e. 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, class, etc.) as well as the more specific ones that exclusively exist on the HTMLInputElement object (such as value, validity, etc.).

Common Errors

Let's see a few more examples of some common errors associated with this issue:

Property 'files' does not exist on type 'EventTarget':

Assuming that the event target is <input type="file">, we can fix this error like so:

// Property 'files' does not exist on type 'EventTarget'.
e.target.files;

// possible fix:
(e.target as HTMLInputElement).files;

Property 'controls' does not exist on type 'EventTarget':

Assuming that the event target is an HTML audio/video element, we can fix this error like so:

// Property 'controls' does not exist on type 'EventTarget'.
e.target.controls;

// possible fixes:
(e.target as HTMLMediaElement).controls;
(e.target as HTMLVideoElement).controls;
(e.target as HTMLAudioElement).controls;

Here, using the HTMLMediaElement should be sufficient. However, we can also do the following when the target element can be either an audio or a video element:

type MediaType = HTMLVideoElement | HTMLAudioElement;
(e.target as MediaType).form;

Property 'form' does not exist on type 'EventTarget':

Assuming that the event target is an HTML input element, we can fix this error like so:

// Property 'form' does not exist on type 'EventTarget'.
e.target.form;

// possible fix:
(e.target as HTMLInputElement).form;

Assuming that the event target is an HTML textarea element, we can fix this error like so:

// Property 'form' does not exist on type 'EventTarget'.
e.target.form;

// possible fix:
(e.target as HTMLTextAreaElement).form;

If the target element can be either an input or a textarea element, we can create a new intersection type like so:

// Property 'form' does not exist on type 'EventTarget'.
e.target.form;

// possible fix:
type InputType = HTMLInputElement | HTMLTextAreaElement;
(e.target as InputType).form;

Property 'checked' does not exist on type 'EventTarget':

Assuming that the event target is an HTML <input type="radio"> or <input type="checkbox"> element, we can fix this error like so:

// Property 'checked' does not exist on type 'EventTarget'.
e.target.checked;

// possible fix:
(e.target as HTMLInputElement).checked;

Property 'src' does not exist on type 'EventTarget':

Assuming that the event target is an HTML <img> element, we can fix this error like so:

// Property 'src' does not exist on type 'EventTarget'.
e.target.src;

// possible fix:
(e.target as HTMLImageElement).src;

Assuming that the event target is an HTML <source> element, we can fix this error like so:

// Property 'src' does not exist on type 'EventTarget'.
e.target.src;

// possible fix:
(e.target as HTMLSourceElement).src;

Property 'classList' does not exist on type 'EventTarget':

The classList property exists on every HTML element, so we could use Element, HTMLElement or a more specific type (for e.g. HTMLInputElement, etc.). For example:

// Property 'classList' does not exist on type 'EventTarget'.
e.target.classList;

// possible fixes:
(e.target as Element).classList;
(e.target as HTMLElement).classList;
// etc.

Property 'parentNode' does not exist on type 'EventTarget':

The parentNode property exists on every HTML element, so we could use Element, HTMLElement or a more specific type (for e.g. HTMLInputElement, etc.). For example:

// Property 'parentNode' does not exist on type 'EventTarget'.
e.target.parentNode;

// possible fixes:
(e.target as Element).parentNode;
(e.target as HTMLElement).parentNode;
// etc.

This post was published 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.