developit / mitt

🥊 Tiny 200 byte functional event emitter / pubsub.
https://npm.im/mitt
MIT License
10.83k stars 439 forks source link

How to declare type of event parameter when listen for event #188

Open vanminhquangtri opened 1 year ago

vanminhquangtri commented 1 year ago

Hello,

I am using mitt 3.0.1 for my Nuxt app (nuxt 3.6.5). I use event-bus to emit/listen for the whole app:

File plugins/event-bus.ts

import mitt from 'mitt';

export default defineNuxtPlugin(() => {
  const emitter = mitt();

  return {
    provide: {
      event: emitter.emit, // Will emit an event
      listen: emitter.on, // Will register a listener for an event
    },
  };
});

I am currently not able to declare event when I listen for event in my components. I have to use type "any" but this break out type safety rules.

$listen('component:display', (event: any) => {
  // here the param I want to declare a specific type rather than type "any"
  // like event: {id?: string; value?: string}
});

I already tried assigned a sepecific type but it throw error:

$listen('component:display', (event:{id?: string; value?: string}) => {
  //
});

ERROR: No overload matches this call.
  Overload 1 of 2, '(type: "*", handler: WildcardHandler<Record<EventType, unknown>>): void', gave the following error.
  Overload 2 of 2, '(type: "component:display", handler: Handler<unknown>): void', gave the following error.ts(2769)

It's now allowed to use flag @ts-ignore in my app so I don't know how to solve this now. I search on document but it seems no mention about this so I hope to receive any advice on this. Thank you so much.

CalebM1987 commented 1 year ago

You just need to define the typings for your Event emitter:

// events.ts
import mitt

type Events = {
  'component:display': { id?: string; value?: string }
}

export const emitter = mitt<Events>()

And in your main.ts or wherever you are setting up nuxt it should infer $listen with the function signatures from emitter.on:

Screenshot 2023-09-08 at 2 06 08 PM