Using TypeScript to Trigger Events in Three.js

After recently diving into Typescript, I encountered an issue when using EventEmitter from the ThreeJS library.

Whenever I attempt to trigger an event:

const event: THREE.EventDispatcher = new THREE.EventDispatcher();
event.addEventListener('test', () => console.log(1));
event.dispatchEvent({ type: 'test' }); // <-- error

An error pops up, stating:

TS2345: Argument of type '{ type: string; }' is not assignable to parameter of type 'never'.

To work around this issue, I tried the following approach:

const event: THREE.EventDispatcher = new THREE.EventDispatcher();
event.addEventListener('test', () => console.log(1));
event.dispatchEvent<any>({ type: 'test' }); // <-- ignored error by any

Despite finding a temporary fix with 'any', it doesn't feel like the optimal solution. Could someone demonstrate the correct method along with explanations?

Answer №1

Within the source code of @types/three, you will find unit tests that serve as useful examples for understanding usage.

I adapted a test from the EventDispatcher module, which can be viewed here:

interface TestEvent {
    test: { message: string };
}

const event = new THREE.EventDispatcher<TestEvent>();
event.addEventListener('test', () => console.log(1));
event.dispatchEvent({ type: 'test', message: "hello world" });

If you desire a detailed explanation (note: I am not an expert in TypeScript):

In examining the type definitions (e.g., by navigating to the definition in VSCode or reviewing the source code), these are the pertinent types:

export interface BaseEvent<TEventType extends string = string> {
    readonly type: TEventType;
}

export class EventDispatcher<TEventMap extends {} = {}> {
    // ...

    dispatchEvent<T extends Extract<keyof TEventMap, string>>(event: BaseEvent<T> & TEventMap[T]): void;
}

This is how the example code functions:

// Declares TEventMap type as { test: { message: string } }
const event = new THREE.EventDispatcher<{ test: { message: string } }>();

// This results in dispatchEvent<"test"> because the key of TEventMap is extracted
// parameter type becomes: event: BaseEvent<"test"> & TEventMap["test"]
// which simplifies to: { type: "test"; } & { message: string; }
// intersection (&) yields: { type: "test"; message: string; } 
event.dispatchEvent({ type: 'test', message: "hello world" });

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

What's the issue with the Global Var in JavaScript (JQuery)?

Why is this code not functioning as expected? I believed that by setting the "prw" and "prh" variables outside of the function where they are calculated, but within the scoping function, it would work. However, it's not! What am I doing incorrectly? ...

Use Selenium to close the Flipkart tab, open a pop-up window, and navigate back to the

WebDriver driver = new FirefoxDriver(); driver.get("https://www.flipkart.com"); driver.manage().window().maximize(); String parentWindowHandler = driver.getWindowHandle(); // Saving the parent window String subWindowHandler = null; Set<String> handle ...

When attempting to trigger an error, the unit test will fail to pass

I am relatively new to Mocha, Chai, and Unit Testing. I'm currently attempting to create a basic test to verify the presence of Authorization headers in the request that passes through my middleware function. Despite trying various approaches such as ...

Load a 3D object or model using three.js and then make modifications to its individual components

Seeking advice on displaying and manipulating a 3D model of a robot arm in a browser. How can I load the model into three.js to manipulate all the sub-parts of the robot arm? Using Inventor, I have an assembly of a rotary motor and a shaft exported as an ...

Add navigation dots to the slider in order to align them with the specified div element

Visit this JSFiddle link for the code <html> <link href="./style.css" rel="stylesheet" type="text/css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script&g ...

Retrieving information stored in a FormBuilder through the HTML

Once I set up a FormBuilder during the onInit Lifecyle: surveyForm: FormGroup; ngOnInit(): void { this.surveyForm = this.formBuilder.group({ 'surveyTitle': new FormControl(null), 'surveyDescription': new FormControl(n ...

The selected value is not displayed in the Material UI select component

My select component is showing the menu items and allowing me to select them, but it's not displaying the selected value. However, its handle function is functioning correctly because when I choose an item, the value in the database gets updated. Bel ...

Basic asynchronous JavaScript and XML (AJAX) call

I am currently learning about ajax and experimenting with a script that involves extracting information from a JSON object and displaying it on the document. Below is an example of the JSON file named companyinfo.json: { 'id':1, 'name&apos ...

Select a single option from the group to include in the array

I'm currently developing a new soccer betting application. My goal is to allow users to choose the result of a match - whether it's a win, loss, or draw - and then save that selection in a list of chosen bets. https://i.stack.imgur.com/hO3uV.png ...

Instructions on utilizing API call ( jssor_slider1.$GoTo(N))

Hi there, I could use some assistance with using the Api Call. I've been attempting to specify a slide using a command, but nothing seems to be working. Sorry for my inexperience, I appreciate your patience. Thank you! <script> function toSli ...

Having trouble utilizing yarn to import Mapbox into TypeScript

My process involves using the command: yarn add --dev @types/mapbox-gl @types/geojson This successfully adds mapbox and geojson to my project. I can see them when attempting to import mapboxgl. Next, I create something similar to this: import * as L ...

Numbering each numeral

Looking to add a sequence number next to each digit using jQuery or JavaScript: If I enter the following numbers: 1, 1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 8, 9, 10 and so on then the desired output should be: 1.1, 1.2, 1.3, 2.1, 3.1, 4.1, 5.1, 5.2, 5.3, 6.1 ...

Creating a Type in Typescript that Inherits Keys from Another Type

Imagine you're faced with this scenario involving a Typescript class: class Person { name: string; age: number; } If you were to create an object type with the same properties, using the any type, but with all properties being optional - how wou ...

The process of flattening an array in Zustand: a comprehensive guide

In my array of brands, each brand object includes a brand name and products. Initially, I successfully added a new brand object to the brands list. However, when attempting to add another brand while keeping the previous brand data intact, it does not fu ...

Deleting database information using Jquery when a div is clicked

I'm looking to create an alert system where users will see a pop-up alert on their screen. However, I am facing a major issue in removing the div completely. I understand that I need to remove it from the database, but I'm struggling with finding ...

The specified dependency, * core-js/fn/symbol, could not be located

I am in the process of developing a Vue.js application with Vuex and have encountered some errors during the build. I attempted to resolve the issue by installing npm install --save core-js/fn/symbol, but unfortunately, it did not work as expected. https:/ ...

Looping through a JSON array and encoding it using the `

I am looking to retrieve data from the database using AJAX and populate a 'select' tag with that data. Each name should be displayed in its own 'option'. Here is the code snippet: Index.php: <label>Select:</label> <sel ...

The initial io.emit message seems to always be delayed or lost in transmission

io.on('connection',function(socket){ console.log('connected'); socket.on('disconnect',()=>{ console.log('a user disconnected'); }); socket.on('sendMessage',function(data){ const message = data.te ...

Troubleshooting: The issue of importing Angular 2 service in @NgModule

In my Angular 2 application, I have created an ExchangeService class that is decorated with @Injectable. This service is included in the main module of my application: @NgModule({ imports: [ BrowserModule, HttpModule, FormsModu ...

Infusing JavaScript with vibrant images

I am currently facing an issue where I am trying to insert images with JavaScript attached to them. Oddly enough, it seems to work fine on Firefox but the images or icons do not display on Internet Explorer. This is how I have written the code: <a hre ...