interface EventGroup { [ eventName ] : Function [ ] ; } export default class Event { _events : EventGroup = { } ; $on < T > ( eventName , fn ) { if ( ! this . _events [ eventName ] ) { this . _events [ eventName ] = [ ] ; } this . _events [ eventName ] . push ( fn ) ; return this ; } $off ( eventName ? , fn ? ) { if ( ! eventName ) { this . _events = { } ; return this ; } const cbs = this . _events [ eventName ] ; if ( ! cbs ) { return this ; } if ( ! fn ) { this . _events [ eventName ] = [ ] ; return this ; } if ( fn ) { let cb ; let i = cbs . length ; while ( i -- ) { cb = cbs [ i ] ; if ( cb === fn || cb . fn === fn ) { cbs . splice ( i , 1 ) ; break ; } } } return this ; } $emit < T > ( eventName , event ? , ... rest ) { let cbs = this . _events [ eventName ] ; if ( cbs ) { cbs . forEach ( ( func ) => func . call ( this , event , ... rest ) ) ; } return this ; } }