javascript – TypeScript – オブジェクトからユニオンを作成

私はタイプスクリプトでEventEmitterを作成しています、そして、私は以下をする方法を考え出すことができません:

私はこのようなインターフェースがあるとします。

interface EventEmitterSubscription { dispose(): void }

// here it is
interface EventEmitter<T extends { [key: string]: any }> {
  onAnyEvent(callback: (event: { type: ???, payload: ??? }) => void): EventEmitterSubscription
  // ...
}

たとえば、次のようなeventEmitterのように、onAnyEventコールバックを入力する方法が見つかりません。

EventEmitter<{ onNumberReceived: number, onCatReceived: { cat: ICat }, onPersonNameReceived: string }>

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(callback:(event:{type: ‘onNumberReceived’、payload:number} | {)を生成するなど、現在は機能しません。
タイプ: ‘onNumberReceived’、ペイロード:{cat:ICat}} | / * … * /)=> void):EventEmitterSubscription

では、onAnyEventフィールドをどのように入力すればよいのでしょうか。

ベストアンサー
共用体を作成する1つの可能な方法は、次のように、希望する共用体の1つの要素の型を持つ各プロパティを持つマップ型を持つことです。

type EventTypeMap<T extends { [key: string]: {} }> =
    { [K in keyof T]: { type: K; payload: T[K] } };

それから一般的な共用体型を定義することができます

type CallbackEventTypes<T extends { [key: string]: {} }> =
     EventTypeMap<T>[keyof EventTypeMap<T>] 

そしてそれを使う

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

転載記事の出典を記入してください: javascript – TypeScript – オブジェクトからユニオンを作成 - コードログ