Guy*_*uff 4 javascript types typescript
我正在用打字稿创建一个 EventEmitter,但我想不出一种方法来执行以下操作:
假设我有一个这样的界面:
interface EventEmitterSubscription { dispose(): void }
// here it is
interface EventEmitter<T extends { [key: string]: any }> {
onAnyEvent(callback: (event: { type: ???, payload: ??? }) => void): EventEmitterSubscription
// ...
}
Run Code Online (Sandbox Code Playgroud)
我找不到一种输入onAnyEvent回调的方法,例如,对于这样的 eventEmitter:
EventEmitter<{ onNumberReceived: number, onCatReceived: { cat: ICat }, onPersonNameReceived: string }>
Run Code Online (Sandbox Code Playgroud)
该onAnyEvent字段将具有类型
onAnyEvent(callback: (event: { type: 'onNumberReceived', payload: number } | { type: 'onCatReceived', payload: { cat: ICat } } | { type: 'onPersonNameReceived', payload: string }) => void): EventEmitterSubscription
Run Code Online (Sandbox Code Playgroud)
目前我的实现界面如下:
onAnyEvent(callback: (event: { type: keyof T, payload: T[keyof T] }) => void): EventEmitterSubscription
Run Code Online (Sandbox Code Playgroud)
除了当前不起作用,例如会产生类型 onAnyEvent(callback: (event: { type: 'onNumberReceived', payload: number } | {
type: 'onNumberReceived', payload: { cat: ICat } } | /* ... */) => void): EventEmitterSubscription
那么如何输入onAnyEvent字段呢?
创建联合的一种可能方法是拥有一个映射类型,每个属性都具有所需联合的一个元素的类型,如下所示:
type EventTypeMap<T extends { [key: string]: {} }> =
{ [K in keyof T]: { type: K; payload: T[K] } };
Run Code Online (Sandbox Code Playgroud)
然后你可以定义通用联合类型
type CallbackEventTypes<T extends { [key: string]: {} }> =
EventTypeMap<T>[keyof EventTypeMap<T>]
Run Code Online (Sandbox Code Playgroud)
并使用它
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2058 次 |
| 最近记录: |