Verify the data type received from the event emitter

I want to develop a strict event emitter for TypeScript, but I'm not sure if it can be done.

Let's say I create a listener for my emitter:

// define listener
@listen('my-custom-event')
function userListener(data: IUser){
  // handle data
}

In this case, I hope TypeScript will verify that the data being sent is of type IUser.

// success case
myEmitter.emit('my-custom-event', myUser as IUser);

// should result in an error
myEmitter.emit('my-custom-event', myNonUser);

Can this be achieved?

Answer №1

Indeed, it is achievable. There is a way in Typescript to validate method types during the compilation phase. The key is to establish a mapping between event names and their corresponding types. Review the code snippet provided below for implementation details.


interface User {
  name: string
}

type EventMap = {
  'my-custom-event': User;
  'my-custom-event-2': number;
}

export class Emitter {
  emit<T extends keyof EventMap>(eventName: T, arg: EventMap[T]) {
    console.log(eventName, arg)
  }
}

const myEmitter = new Emitter

myEmitter.emit('my-custom-event', {name: 'Henry'}) // This operation succeeds

myEmitter.emit('my-custom-event', {age: 10}) // This operation fails at compile time as expected

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

Guide on transforming an array of objects into a fresh array

I currently have this array: const initialData = [ { day: 1, values: [ { name: 'Roger', score: 90, }, { name: 'Kevin', score: 88, }, { name: 'Steve&apo ...

Is it Control or ControlGroup in Angular 2 - How to tell the difference?

let aa = this._formBuilder.control(""); let bb = this._formBuilder.group({ aa: aa }; I am trying to achieve the following: if (typeof(aa) == "Control") { // perform a specific action } else if (typeof(aa) == "ControlGroup") { // perform anoth ...

What is the best way to create a jumping animation for an object in Cannon.js and Three.js?

During my quest for a solution, I came across a common practice where users used cannonBody.velocity.y = JUMP_VELOCITY to make an object jump. However, in my scenario, this method only worked while the object was already in motion and not when it was stat ...

An error occurred: The property 'toUpperCase' cannot be read of an undefined Observable in an uncaught TypeError

Encountering an issue during the development of a mobile app using the ionic framework for a movie application. After finding an example on Github, I attempted to integrate certain functions and designs into my project. The problem arises with the 'S ...

Puppeteer: What is the best way to interact with a button that has a specific label?

When trying to click on a button with a specific label, I use the following code: const button = await this.page.$$eval('button', (elms: Element[], label: string) => { const el: Element = elms.find((el: Element) => el.textContent === l ...

Stringified HTML code showcased

When working with Angular, I have encountered an issue where I am calling a function inside an .html file that returns a string containing a table element. My goal is to convert this string into HTML code. I attempted to use [innerHtml]: <p [innerHtml ...

Angular 6 Checkbox Selector - Filtering Made Easy

How can I filter a list of JSON objects (Products) by the 'category' variable using checkboxes? An example product object is shown below: { 'bikeId': 6, 'bikeName': 'Kids blue bike', 'bikeCode': ...

Executing a TypeScript function through a package.json script: A guide

I'm currently using a javascript function from my package.json script, but I want to switch it to a typescript function in a typescript file. Can someone advise me on how to make this adjustment? This is the javascript code that runs the desired func ...

Utilizing Jest and nest.js for testing with absolute paths

Looking at my jest configuration inside the package.json: "jest": { "moduleFileExtensions": [ "js", "json", "ts" ], "moduleDirectories":["node_modules", "src" ...

Retrieve the document id along with the corresponding data from a collection

Retrieving data from the collection leads and displaying all documents in an HTML table. Upon clicking, I need to extract the document ID of the clicked item as it serves as the sole primary key. P.S I am able to obtain records of all documents in an arra ...

Enable automatic conversion of interfaces to JsonData

Is it possible to tweak this Json data type definition to allow json-compatible types to automatically convert to it? type JsonValue = | string | number | boolean | null | { [property: string]: JsonValue } | JsonValue[]; Consider t ...

Webpack 5: Updating the file path for TypeScript declaration files

My project structure includes a crucial src/ts folder: - dist/ - js/ - css/ - index.html - about.html - src/ - assets/ - fonts/ - images/ - sass/ - ts/ - services/ - service1.ts - ...

Encountering the issue: "Unable to establish validator property on string 'control'"

Has anyone encountered this error message before? TypeError: Cannot create property 'validator' on string 'control'" import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core'; import { CommonModule } from &ap ...

Using TypeScript and Angular to modify CSS properties

I'm trying to figure out how to change the z-index CSS attribute of the <footer> element when the <select> is open in TypeScript (Angular 10). The current z-index value for the footer is set to 9998;, but I want it to be 0;. This adjustmen ...

What causes the distinction between entities when accessing objects through TestingModule.get() and EntityManager in NestJS?

Issue: When using TestingModule.get() in NestJS, why do objects retrieved from getEntityManagerToken() and getRepositoryToken() refer to different entities? Explanation: The object obtained with getEntityManagerToken() represents an unmocked EntityManag ...

Sending SMS from an Angular application to mobile devices can be achieved through several methods

Does anyone have experience sending SMS from an Angular6 web application? I would appreciate any guidance, such as reference links or code samples. Thank you! ...

What is the term for specifying a variable's data type using a set of values instead of a traditional type?

Recently, I stumbled upon some code that introduces a class with specific variables defined in an unconventional manner. export class Foo { id: string = "A regular string" bar: '>' | '<' | '=' | '<=' | ...

Having trouble assigning a value of `undefined` to a TextField state in React hook

I am in need of setting the initial state for a TextField date to be undefined until the user makes a selection, and then allowing the user an easy way to reset the date back to undefined. In the code snippet below, the Reset button effectively resets par ...

React with TypeScript: Initial submission results in an empty array

I'm struggling to create a basic form using React and Typescript. I've set up some input fields and linked them with an onChange event to update a main state object. However, when I try to submit the form for the first time, it always returns emp ...

Converting UK DateTime to GMT time using Angular

I am currently working on an angular project that involves displaying the start and end times of office hours in a table. For instance, the office operates from 8:30 AM to 5:30 PM. This particular office has branches located in the UK and India. Since u ...