function isArrayLike ( a ) { return a && typeof a . length === 'number' ; } function toStringArray ( arr ) { return ( 'array with ' + arr . length + ' items.\n[' + arr . map ( toString ) . join ( ',' ) + ']\n' ) ; } function isPrimitive ( arg ) { return ( typeof arg === 'string' || typeof arg === 'number' || typeof arg === 'boolean' ) ; } function isError ( e ) { return e instanceof Error ; } function replacer ( key , value ) { if ( value === undefined ) { return null ; } return value ; } function toString ( arg , k ) { if ( arg === null ) { return 'null' ; } if ( arg === undefined ) { return 'undefined' ; } if ( isPrimitive ( arg ) ) { return JSON . stringify ( arg ) ; } if ( arg instanceof Error ) { return arg . name + ' ' + arg . message ; } if ( Array . isArray ( arg ) ) { return toStringArray ( arg ) ; } if ( isArrayLike ( arg ) ) { return toStringArray ( Array . prototype . slice . call ( arg , 0 ) ) ; } var argString ; try { argString = JSON . stringify ( arg , replacer , 2 ) ; } catch ( err ) { argString = '{ cannot stringify arg ' + k + ', it has type "' + typeof arg + '"' ; if ( typeof arg === 'object' ) { argString += ' with keys ' + Object . keys ( arg ) . join ( ', ' ) + ' }' ; } else { argString += ' }' ; } } return argString ; } function endsWithNewLine ( s ) { return /\n$/ . test ( s ) ; } function formMessage ( args ) { var msg = args . reduce ( function ( total , arg , k ) { if ( k && ! endsWithNewLine ( total ) ) { total += ' ' ; } if ( typeof arg === 'string' ) { return total + arg ; } if ( typeof arg === 'function' ) { var fnResult ; try { fnResult = arg ( ) ; } catch ( err ) { fnResult = '[function ' + arg . name + ' threw error!]' ; } return total + fnResult ; } var argString = toString ( arg , k ) ; return total + argString ; } , '' ) ; return msg ; } function lazyAssLogic ( condition , ... args ) { if ( isError ( condition ) ) { return condition ; } var fn = typeof condition === 'function' ? condition : null ; if ( fn ) { condition = fn ( ) ; } if ( ! condition ) { if ( fn ) { args . unshift ( fn . toString ( ) ) ; } return new Error ( formMessage ( args ) ) ; } } interface LazyAss { ( condition , ... args ) : void ; async : ( condition : any , ... args : any [ ] ) => void ; } export const lazyAss = < LazyAss > ( function lazyAss ( condition , ... args ) { var err = lazyAssLogic ( condition , ... args ) ; if ( err ) { throw err ; } } ) ; export const lazyAssync = function lazyAssync ( condition , ... args ) { var err = lazyAssLogic ( condition , ... args ) ; if ( err ) { setTimeout ( function ( ) { throw err ; } , 0 ) ; } } ; lazyAss . async = lazyAssync ; export default lazyAss ;