Using Typescript to add event listeners and set the event type

I'm attempting to accomplish this

document.addEventListener('click', (e: MouseEvent) => { ...

However, Typescript is unable to determine the precise event type based on the event name.

'click' => MouseEvent

and considers the type of e to be Event. As per the definition provided

declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
    
interface EventListener {
    (evt: Event): void;
}
    
interface EventListenerObject {
    handleEvent(evt: Event): void;
}

This obviously leads to an error message

TS2345: Argument of type '(e: MouseEvent) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject'. Type '(e: MouseEvent) > void' is not assignable to type 'EventListener'. Types of parameters 'e' and 'evt' are incompatible. Type 'Event' is missing the following properties from type 'MouseEvent': altKey, button, buttons, clientX, and 25 more.

How can I inform Typescript that e is indeed of type MouseEvent? Or more broadly, how can I correctly type addEventListener?

Answer №1

In the latest update of version 3.3.3333, a new method was introduced in the lib.dom.ts file.

    addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;

    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;

This method utilizes an interface called DocumentEventMap, which is an extension of the GlobalEventHandlersEventMap containing event declarations such as the click event.

interface GlobalEventHandlersEventMap {
    ...
    "click": MouseEvent;
    ...
}

In the first type signature mentioned above, the type parameter represents a key K from the DocumentEventMap, and the ev parameter's type is mapped to DocumentEventMap[K]. This allows the compiler to correctly infer the type for the event in the callback function.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Struggling to grasp the concept of call signatures

I'm a bit confused about call signatures in Typescript. I've come across them and read some information, but I'm still not clear on what exactly they do. The Typescript documentation explains: When we want to describe something that is cal ...

"An identifier was expected causing a parsing error" triggered by v-on:change

Encountered an issue where importing a class to be used solely as a typescript type annotation resulted in a no-unused vars error. Following advice from this discussion thread, I added "plugin:@typescript-eslint/recommended" to the eslint config, ...

Handling functions in Ant Design Select component with TypeScript types

I have a query. Antd offers a custom Select input with functions like onSelect, onChange, etc. I am utilizing the onSelect function which requires the following arguments: (JSX attribute) onSelect?: ((value: string | number | LabeledValue, option: OptionDa ...

What is preventing the availability of those array extensions during runtime?

Looking for a simple way to work with arrays, I decided to create this custom extension class: export class ArrayType<T extends IEntity> extends Array<T> { add(item: T) { this.push(item); } remove(item: T) { console.log(item); ...

What is the best way to store a logged-in user's email in a React

I have implemented a login API and I would like to save the email of the logged-in user in the state or another variable, so that I can display it in the header after successful login. The user's email is located in the data.email. The following code ...

What is the best way to divide text into key-value pairs using JavaScript?

I have data in text format from my Raspberry Pi that I need to insert into MongoDB as key-pair values or JSON for my Node.js Application. I'm relatively new to JavaScript and I'm looking for a solution. Any suggestions would be greatly appreciate ...

Protractor enables horizontal scrolling for a Div element

My struggle to scroll to the right persists despite all attempts I experimented with various solutions, but none seem to work await browser.executeScript('arguments[0].scrollIntoView(true)',element.getWebElement()) The issue still remains unr ...

Tailored component properties for React applications

I am currently working on configuring discriminative component props. Check out my code snippet below: import React, { ReactNode } from 'react' type SelectionModalProps<T> = ( | { multiSelect: true onSubmit: (data: T[]) => ...

Issue with Props Type Check not functioning as expected in Typescript with React

I am utilizing Typescript within my React application. I aim to rigorously verify the type of props being passed to my components and trigger an error if it does not match. import React from "react"; import styles from "./ServiceDetailCard.css"; type Ser ...

Following the build process with the --prod flag in Ionic 3, users may encounter a situation where

Encountering an issue only when using --prod on Android phones. Strangely, touching anywhere triggers the event that should be fired at that specific location, causing the content to suddenly appear. I came across information suggesting a conflict between ...

Jest encounters a TypeError when interacting with Bootstrap-Vue

I am currently utilizing Bootstrap-Vue ^2.23.1 along with Vuejs and vue/compat ^3.2.45, and my testing library is jest ^29.3.1. However, when I include the BootstrapVue plugin in my tests, it triggers the following error: TypeError: Cannot read properties ...

Develop a TypeScript class that includes only a single calculated attribute

Is it advisable to create a class solely for one computed property as a key in order to manage the JSON response? I am faced with an issue where I need to create a blog post. There are 3 variations to choose from: A) Blog Post EN B) Blog Post GER C) Bl ...

"Hmm, the React context's state doesn't seem to be changing

I have been working on a next.js app and I encountered an issue related to using react context to export a state. Despite my efforts, the state doesn't seem to update and it remains stuck at the initial value defined by the createContext hook, which i ...

Can you explain how this promise functions within the context of the mutation observer, even without an argument?

Recently, I came across a mutation observer in some TypeScript code that has left me puzzled. This particular implementation of a promise within the mutation observer seems unconventional to me: const observer = new MutationObserver((mutations: MutationR ...

How to redefine TypeScript module export definitions

I recently installed a plugin that comes with type definitions. declare module 'autobind-decorator' { const autobind: ClassDecorator & MethodDecorator; export default autobind; } However, I realized that the type definition was incorrec ...

Angular: Streamlining the Constructor Function for Efficiency

Consider the scenario where we have these two components: export class HeroComponent { constructor( public service1: Service1, public service2: Service2, ) { // perform some action } } export class AdvancedHeroComponent extends HeroCompone ...

adjusting the scrollbar to be positioned at the top when using Material UI stepper component

While using the material ui stepper, I encountered an issue where the scroll bar remains static and hidden behind the step number header when I click on the "save and continue" button. I expect that upon clicking the button, the scroll bar should automatic ...

Error message "ERR_FILE_NOT_FOUND" displayed in Ionic Dailymotion iframe player

While viewing the app on a browser, the video player functions properly. However, when accessed on a phone, the following error occurs. I suspect that the issue lies in the 'file:' prefix, but I am unable to remove it using string.replace('f ...

Oops! An issue occurred during the `ng build` command, indicating a ReferenceError with the message "Buffer is not defined

I'm facing an issue while trying to utilize Buffer in my angular component ts for encoding the Authorization string. Even after attempting npm i @types/node and adding "node" to types field in tsconfig.json, it still doesn't compile with ng buil ...

Angular 13: Issue with displaying lazy loaded module containing multiple outlets in a component

Angular version ^13.3.9 Challenge Encountering an issue when utilizing multiple outlets and attempting to render them in a lazy module with the Angular router. The routes are being mapped correctly, but the outlet itself is not being displayed. Sequence ...