Advertisement
Telokis

Strict event emitter Typescript

Apr 19th, 2019
508
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. type PickMembers<T, K extends keyof T> = {
  2.     [P in K]: T[P]
  3. };
  4.  
  5. type BadCallback = (arg?: any) => void;
  6.  
  7. class FakeEventEmitter {
  8.     data: {
  9.         [key: string]: BadCallback[];
  10.     } = {};
  11.  
  12.     on(name: string, callback: BadCallback) {
  13.         if (!this.data[name]) {
  14.             this.data[name] = [];
  15.         }
  16.  
  17.         this.data[name].push(callback);
  18.     }
  19.  
  20.     emit(name: string, data?: any) {
  21.         if (!this.data[name]) {
  22.             return;
  23.         }
  24.  
  25.         this.data[name].forEach(cb => {
  26.             cb(data);
  27.         });
  28.     }
  29. }
  30.  
  31. type KeysOfType<
  32.     Terface,
  33.     Filter,
  34.     K extends keyof Terface = keyof Terface
  35. > = K extends (Terface[K] extends Filter ? K : never) ? K : never;
  36.  
  37. interface TypedEventEmitter<
  38.     Events,
  39.     VoidKeys extends KeysOfType<Events, void> = KeysOfType<Events, void>,
  40.     NotVoidKeys extends Exclude<keyof Events, VoidKeys> = Exclude<keyof Events, VoidKeys>
  41. > {
  42.     on<K extends NotVoidKeys>(
  43.         eventName: K,
  44.         callback: (payload: Events[K]) => void
  45.     ) : void;
  46.     emit<K extends NotVoidKeys>(eventName: K, payload: Events[K]) : void;
  47.  
  48.     on<K extends VoidKeys>(
  49.         eventName: K,
  50.         callback: () => void
  51.     ) : void;
  52.     emit<K extends VoidKeys>(eventName: K) : void;
  53. }
  54.  
  55. type StrictEventEmitter<Events,EventEmitter> = TypedEventEmitter<Events> &
  56.     PickMembers<
  57.         EventEmitter,
  58.         Exclude<keyof EventEmitter, keyof TypedEventEmitter<Events>>
  59.     >;
  60.  
  61. interface Point {
  62.     x: number;
  63.     y: number;
  64. }
  65.  
  66. interface Events {
  67.     BasicMessage: string;
  68.     NumberMessage: number;
  69.     PosMsg: Point;
  70.     VoidMsg: void;
  71. }
  72.  
  73. const ee: StrictEventEmitter<Events, FakeEventEmitter> = new FakeEventEmitter();
  74.  
  75. ee.emit("VoidMsg");
  76.  
  77. ee.emit("PosMsg", 145);
  78. ee.emit("PosMsg", { x: 1, y: 2 });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement