Javascript TypeScript-从对象创建联合
我正在用typescript创建EventEmitter,但我想不出一种方法来执行以下操作: 假设我有这样一个界面:Javascript TypeScript-从对象创建联合,javascript,typescript,types,Javascript,Typescript,Types,我正在用typescript创建EventEmitter,但我想不出一种方法来执行以下操作: 假设我有这样一个界面: interface EventEmitterSubscription { dispose(): void } // here it is interface EventEmitter<T extends { [key: string]: any }> { onAnyEvent(callback: (event: { type: ???, payload: ???
interface EventEmitterSubscription { dispose(): void }
// here it is
interface EventEmitter<T extends { [key: string]: any }> {
onAnyEvent(callback: (event: { type: ???, payload: ??? }) => void): EventEmitterSubscription
// ...
}
EventEmitter<{ onNumberReceived: number, onCatReceived: { cat: ICat }, onPersonNameReceived: string }>
type EventTypeMap<T extends { [key: string]: {} }> =
{ [K in keyof T]: { type: K; payload: T[K] } };
onAnyEvent字段的类型为
onAnyEvent(callback: (event: { type: 'onNumberReceived', payload: number } | { type: 'onCatReceived', payload: { cat: ICat } } | { type: 'onPersonNameReceived', payload: string }) => void): EventEmitterSubscription
目前,我的实现的界面如下所示:
onAnyEvent(callback: (event: { type: keyof T, payload: T[keyof T] }) => void): EventEmitterSubscription
除了当前不起作用之外,例如,它将生成类型onAnyEvent(回调:(事件:{type:'onNumberReceived',负载:number}{
键入:“onNumberReceived”,有效负载:{cat:ICat}}|/*…*/)=>void:EventEmitterSubscription
那么,我如何键入onAnyEvent字段?创建联合的一种可能方法是使用映射类型,每个属性都具有所需联合的一个元素的类型,如下所示:
interface EventEmitterSubscription { dispose(): void }
// here it is
interface EventEmitter<T extends { [key: string]: any }> {
onAnyEvent(callback: (event: { type: ???, payload: ??? }) => void): EventEmitterSubscription
// ...
}
EventEmitter<{ onNumberReceived: number, onCatReceived: { cat: ICat }, onPersonNameReceived: string }>
type EventTypeMap<T extends { [key: string]: {} }> =
{ [K in keyof T]: { type: K; payload: T[K] } };
type EventTypeMap=
{[K in keyof T]:{type:K;payload:T[K]};
然后可以定义泛型联合类型
type CallbackEventTypes<T extends { [key: string]: {} }> =
EventTypeMap<T>[keyof EventTypeMap<T>]
type CallbackEventTypes=
EventTypeMap[keyof EventTypeMap]
并使用它
interface EventEmitterSubscription { dispose(): void }
interface EventEmitter<T extends { [key: string]: {} }> {
onAnyEvent(callback: (event: CallbackEventTypes<T>) => void): EventEmitterSubscription
// ...
}
interface ICat { meow() }
type Emitter = EventEmitter<{ onNumberReceived: number, onCatReceived: { cat: ICat }, onPersonNameReceived: string }>
type HandlerType = Emitter['onAnyEvent'];
// inferred as
//type HandlerType =
// (callback: (event: { type: "onNumberReceived"; payload: number; }
// | { type: "onCatReceived"; payload: { cat: ICat; }; }
// | { type: "onPersonNameReceived"; payload: string; }
// ) => void) => EventEmitterSubscription
接口EventEmitterSubscription{dispose():void}
接口事件发射器{
onAnyEvent(回调:(事件:CallbackEventTypes)=>void):EventEmitterSubscription
// ...
}
接口ICat{meow()}
类型发射器=事件发射器
类型HandlerType=发射器['onAnyEvent'];
//推断为
//类型HandlerType=
//(回调:(事件:{type:“onNumberReceived”;负载:number;}
//|{type:“onCatReceived”;有效负载:{cat:ICat;};}
//|{type:“onPersonNameReceived”;有效负载:string;}
//)=>void=>EventEmitterSubscription
这正是我要找的!杰出的