Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获取参数类型为U的类型为T的类型为T的函数的参数类型_Javascript_Reactjs_Typescript - Fatal编程技术网

Javascript 获取参数类型为U的类型为T的类型为T的函数的参数类型

Javascript 获取参数类型为U的类型为T的类型为T的函数的参数类型,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,我试图键入一个事件总线,其中我有一个特定的事件,它有特定的参数。基本结构是: connection.on("myEvent", (args) => {}); 例如: connection.on("OnProductAdded", (productName, id) => console.log(`Product: ${productName} added with id: ${id})); 我在实际事件广播和消费者之间有一个事件总线类型层,这就是我想要类型信息的地方。我有一个函数

我试图键入一个事件总线,其中我有一个特定的事件,它有特定的参数。基本结构是:

connection.on("myEvent", (args) => {});
例如:

connection.on("OnProductAdded", (productName, id) => console.log(`Product: ${productName} added with id: ${id}));
我在实际事件广播和消费者之间有一个事件总线类型层,这就是我想要类型信息的地方。我有一个函数,它通过回调将使用者订阅到特定事件:

function subscribe<T extends keyof EventArgs>(id: string, event: Events, callback: (args: EventHanddlers[T] => void){
    subscriberList.add({id: id, event: event, callback: callback});
}
这将在消费代码中由以下内容调用:

const { connectionStatus, subscribe } = useEvents();

subscribe<OnProductAdded>("my_consumer_id", (args) => doSomethingOnTheEvent(args));
上下文的完整非工作wip代码:

const useEvents = () => {
    const { connection } = useContext(EventsContext);
    const { array: subscriptions, api: mutateSubscriptions } = useStateArray<Subscriber>([]); // A data structure around arrays to make them nice in react states. The important part is it's Subscriber[];


    //The idea of this function is to find all subscribers who subscribed to event of type T, and call all the callbacks with the parameters received on the event.
    function callAllSubscribers(args: EventHandlers) {
        const eventSubscriberList = subscriptions.filter(x => x.event == event);

        for (const sub of eventSubscriberList) {
            sub.callback(args)

        }

    }

    function subscribe<T extends keyof EventArgs>(id: string, event: Events, callback: EventHandlers[T]) {
        mutateSubscriptions.add({ id, event, callback: callback })
    }

//Wiring all events up. The library fires off events that are bound like normal with .on("eventStringName", (...args) => void);
//My initial idea was to wire them up by looping over all defined events, but currently I could only find a way to do it by manually wiring it up.
connection?.on("onProductAdded", (args: EventArgs[onProductAdded]) => callAllSubscribers(args));

    return { connectionStatus: connection?.state, subscribe };
}
const usevents=()=>{
const{connection}=useContext(EventsContext);
const{array:subscriptions,api:mutateSubscriptions}=useStateArray([]);//一种围绕数组的数据结构,可以使它们在反应状态下保持良好状态。重要的部分是它的订户[];
//此函数的思想是查找订阅T类型事件的所有订阅者,并使用事件上接收到的参数调用所有回调。
函数callAllSubscribers(参数:EventHandlers){
const eventSubscriberList=subscriptions.filter(x=>x.event==event);
for(事件订阅列表的const sub){
sub.callback(args)
}
}
函数订阅(id:string,event:Events,callback:EventHandlers[T]){
添加({id,事件,回调:callback})
}
//将所有事件连接起来。库将触发与.on绑定的事件(eventStringName,(…args)=>void);
//我最初的想法是通过在所有定义的事件上循环来连接它们,但目前我只能通过手动连接找到一种方法。
连接?.on(“onProductAdded”,(args:EventArgs[onProductAdded])=>callAllSubscribers(args));
返回{connectionStatus:connection?.state,subscribe};
}

Typescript是先驱,它不应该依赖于值。因此,如果您有预定义事件的列表,可以尝试重载函数声明:

on(eventName: string, handler: (args: any) => void);
on(eventName: string, handler: (id: string) => void);
on(eventName: string, handler: (productName: string, id: string) => void);
但是,如果希望基于这些值创建类型结构,可以尝试以下方法。但是我不确定这是否是最好的选择

想法:
  • 为事件类型创建类别
  • 定义类别的接口/类型
  • 对上的
    使用这些类型的并集。这将定义如果
    eventName
    是给定的枚举,则处理程序将具有此类型
enum IdBasedEvents{
PRODUCT_DELETE='onProductDelete'
}
枚举名称和属性{
产品添加='onProductAdd'
}
枚举泛型事件{
MY_事件='myEvent'
}
类型targetSevent=(args:any)=>void;
键入TProductAddEvent=(productName:string,id:string)=>void;
输入TProductDeleteEvent=(id:string)=>void;
类型targetEventHandler=(事件名称:GenericeEvents,处理程序:targetSevent)=>void;
键入TProductAddHandler=(事件名称:nameandEvents,处理程序:TProductAddEvent)=>void;
键入TProductDeleteHandler=(eventName:IdBasedEvents,handler:TProductDeleteEvent)=>void;
接口I连接{
on:TargetEventHandler | TProductAddHandler | TProductDeleteHandler
}
使用泛型:

type Subscriber<T extends Events> {
    id: string;
    event: T;
    callback: EventHandlers<T>; 
}

type OnProductAdded = 'OnProductAdded';
type OnProductDeleted = 'OnProductDeleted';

type Events = OnProductAdded | OnProductDeleted;     

type EventArgs = {
    OnProductAdded: { productName: string; id: string; };
    OnProductDeleted: { id: string };
}

type EventHandlers<T extends Events> = {
    [T in keyof EventArgs]: (args: T) => void;
}

function /*connection.*/on<T extends Events>(type: T, cb: EventHandlers<T>) {

}
类型订户{
id:字符串;
事件:T;
回调:事件处理程序;
}
类型OnProductAdded='OnProductAdded';
类型OnProductDeleted='OnProductDeleted';
类型事件=OnProductAdded | OnProductDeleted;
类型EventArgs={
OnProductAdded:{productName:string;id:string;};
OnProductDeleted:{id:string};
}
类型EventHandlers={
[T in keyof EventArgs]:(args:T)=>void;
}
函数/*连接.*/on(类型:T,cb:EventHandlers){
}

输入OnProductAdded='OnProductAdded'应该是
枚举
而不是
类型
,您试图实现基于值的类型定义。这在概念上是错误的
on(eventName: string, handler: (args: any) => void);
on(eventName: string, handler: (id: string) => void);
on(eventName: string, handler: (productName: string, id: string) => void);
type Subscriber<T extends Events> {
    id: string;
    event: T;
    callback: EventHandlers<T>; 
}

type OnProductAdded = 'OnProductAdded';
type OnProductDeleted = 'OnProductDeleted';

type Events = OnProductAdded | OnProductDeleted;     

type EventArgs = {
    OnProductAdded: { productName: string; id: string; };
    OnProductDeleted: { id: string };
}

type EventHandlers<T extends Events> = {
    [T in keyof EventArgs]: (args: T) => void;
}

function /*connection.*/on<T extends Events>(type: T, cb: EventHandlers<T>) {

}