type FunctionParameters < T extends ( ... args : any [ ] ) => any > = T extends ( ... args : infer P ) => any ? P : never ; export class EventEmitter < CallbackSignature extends ( ... args : any [ ] ) => any > { handlers : Array < CallbackSignature > = [ ] ; register ( cb , once = false ) { this . handlers . push ( cb ) ; return this ; } invoke ( ... args ) { this . handlers . forEach ( ( handler ) => handler . apply ( this , args ) ) ; } invokeAsync ( ... args ) { return Promise . all ( this . handlers . map ( ( handler ) => handler . apply ( this , args ) ) ) ; } remove ( cb ) { const index = this . handlers . indexOf ( cb ) ; this . handlers [ index ] = this . handlers [ this . handlers . length - 1 ] ; this . handlers . pop ( ) ; } clear ( ) { this . handlers = [ ] ; } } export function createSignal < CallbackSignature extends ( ... args : any [ ] ) => void | Promise < any > > ( ) { const emitter = new EventEmitter < CallbackSignature > ( ) ; function register ( this , cb ) { return emitter . register ( cb , this === null ) ; } ; register . once = ( cb ) => { const callback = function ( ... args ) { cb . apply ( this , args ) ; emitter . remove ( callback ) ; } ; emitter . register ( callback ) ; } ; register . remove = ( cb ) => emitter . remove ( cb ) ; register . invoke = ( ... args ) => emitter . invoke ( ... args ) ; register . invokeAsync = ( ... args ) => emitter . invokeAsync ( ... args ) ; register . clear = ( ) => emitter . clear ( ) ; return register ; }