import { AxiosPromise , AxiosResponse } from 'axios' ; interface ModelAttributes < T > { set ( value ) : void ; getAll ( ) : T ; get < K extends keyof T > ( key ) : T [ K ] ; } interface Sync < T > { fetch ( id ) : AxiosPromise ; save ( data ) : AxiosPromise ; } interface Events { on ( eventName , callback ) : void ; trigger ( eventName ) : void ; } interface HasId { id ? : number ; } export class Model < T extends HasId > { constructor ( private attributes , private events , private sync ) { } on = this . events . on ; trigger = this . events . trigger ; get = this . attributes . get ; set ( update ) { this . attributes . set ( update ) ; this . events . trigger ( 'change' ) ; } fetch ( ) { const id = this . get ( 'id' ) ; if ( typeof id !== 'number' ) { throw new Error ( 'Cannot fetch without an id' ) ; } this . sync . fetch ( id ) . then ( ( response ) : void => { this . set ( response . data ) ; } ) ; } save ( ) { this . sync . save ( this . attributes . getAll ( ) ) . then ( ( response ) : void => { this . trigger ( 'save' ) ; } ) . catch ( ( ) => { this . trigger ( 'error' ) ; } ) ; } }