interface EventsInterface { [ propName ] : Function [ ] ; } export default class Events { events : EventsInterface ; container : HTMLVideoElement ; constructor ( container ) { this . container = container ; this . events = { } ; } nativeOn ( event , fn ) { console . log ( this . container ) ; this . container . addEventListener . call ( this . container , event , fn as EventListenerOrEventListenerObject , false ) ; } removeNative ( event , fn ) { this . container . removeEventListener . call ( this . container , event , fn as EventListenerOrEventListenerObject ) ; } on ( eventName , fn ) { if ( ! this . events [ eventName ] ) { this . events [ eventName ] = [ fn , ... this . events [ eventName ] ] ; } } emit ( eventName , ... args ) { if ( ! eventName ) throw Error ( `${ eventName } is not defined` ) ; for ( const event of Object . entries ( this . events ) ) { console . log ( eventName , event [ 0 ] ) ; if ( eventName === event [ 0 ] ) { event [ 1 ] . map ( fn => { fn . call ( this , ... args ) ; } ) ; } } } remove ( eventName , fn ? ) { if ( fn ) { const index = this . events [ eventName ] . findIndex ( item => fn === item ) ; this . events [ eventName ] . splice ( index , 1 ) ; } else { delete this . events [ eventName ] ; } } }