obs-websocket-community-projects / obs-websocket-js

Consumes https://github.com/obsproject/obs-websocket
MIT License
680 stars 96 forks source link

Expose typed EventHandlersDataMap #265

Open artdevgame opened 3 years ago

artdevgame commented 3 years ago

Description:

This could just be that I'm a novice with TypeScript, but I'm using this library in my project and I would like to reference the EventHandlersDataMap type. I don't think I can currently do that as the file concerned isn't available in node_modules.

I've tried getting hold of the map with this, but it feels hacky/wrong and I'm still unsure how to type an event handler to a specific use-case:

import ObsWebSocket from 'obs-websocket-js';

const obs = new ObsWebSocket();

type OnParams = Parameters<typeof obs.on>;

export type EventHandlerKey = OnParams[0];
export type EventHandlerListener = OnParams[1];

export type ObsSocketListener = Partial<Record<EventHandlerKey, EventHandlerListener>>;

This is how I'm trying to get a specific data map for an event handler:

type ProfileChangedHandler = Extract<EventHandlerListener, { profile: string; }> // <- Always returns 'never'

// expecting `ProfileChangeHandler` to be `{ profile: string; }`

It looks like obsWebsocket.ts would be a lot easier to do this kind of thing, is that possible?

Versions Used (if applicable):

artdevgame commented 3 years ago

I've managed to figure out how to get to it in a really long-winded way, but would still prefer the file exposed in the package if possible, this is my solution:

type ProfileChangedHandler = Extract<Parameters<EventHandlerListener>[0], { profile: string; }>;

Evaluates as:

type ProfileChangedHandler = {
    profile: string;
}
polerin commented 2 years ago

Agree, I was really confused when this wasn't exposed.

polerin commented 2 years ago

I've exported all of the EventHandlersData params in a way that is similar to @artdevgame, but I don't think there's a way for me to do dynamic registration of listeners in a manner similar to below


    protected registerEventTransformers(transformers : V4EventTransformerSet) : void 
    {
        for (const transformer of transformers) {
            this.transformerRegistery[transformer.obsEventType] = transformer;

            this.websocket.on(transformer.obsEventType, this.notifyListener.bind(this, transformer.obsEventType, transformer));
        }
    }

    protected notifyListener<EventType extends ObsV4EventNames>(obsEventType : EventType, transformer : V4EventTransformer, eventData : ObsV4EventHandlersData[EventType]) : void 
    {
        if (this.callback) {
            this.callback(transformer.systemMessageType, transformer.buildSystemMessage(eventData));
        }
    }

I know y'all are probably full steam ahead on v5, but it is sort of a major roadblock for me. Any help?