import { GenericMeasure } from "./genericMeasure" ; import { BinaryFn , PrefixFn , SpreadFn } from "./genericMeasureUtils" ; import { AllowedExponents , DivideUnits , DivisorUnit , ExponentiateUnit , MultiplicandUnit , MultiplyUnits , Unit , } from "./unitTypeArithmetic" ; export interface GenericMeasureStatic < N > { /** Sums a list of one or more measures, all of the same unit. */ sum : SpreadFn < N > ; /** Returns the smallest of a list of one or more measures. */ min : SpreadFn < N > ; /** Returns the largest of a list of one or more measures. */ max : SpreadFn < N > ; /** Static version of `left.plus(right)` */ add : BinaryFn < N > ; /** Static version of `left.minus(right)` */ subtract : BinaryFn < N > ; /** Static version of `left.times(right)` */ multiply < L extends Unit , R extends MultiplicandUnit < L > > ( left , right ) : GenericMeasure < N , MultiplyUnits < L , R > > ; /** Static version of `left.div(right)` */ divide < L extends Unit , R extends DivisorUnit < L > > ( left , right ) : GenericMeasure < N , DivideUnits < L , R > > ; /** Static version of `value.toThe(exp)` */ pow < U extends Unit , E extends AllowedExponents < U > > ( value , exp ) : GenericMeasure < N , ExponentiateUnit < U , E > > ; param prefix param multiplier returns prefix ( prefix , multiplier ) : PrefixFn < N > ; } export const getGenericMeasureStaticMethods = < N > ( ) : GenericMeasureStatic < N > => ( { sum : reduce ( ( prev , curr ) => prev . plus ( curr ) ) , min : reduce ( ( min , curr ) => ( curr . lt ( min ) ? curr : min ) ) , max : reduce ( ( max , curr ) => ( curr . gt ( max ) ? curr : max ) ) , add : ( left , right ) => left . plus ( right ) , subtract : ( left , right ) => left . minus ( right ) , multiply : ( left , right ) => left . times ( right ) , divide : ( left , right ) => left . over ( right ) , pow : ( value , exp ) => value . toThe ( exp ) , prefix : ( prefix , multiplier ) => { return measure => { const { symbol } = measure ; return measure . scale ( multiplier ) . withSymbol ( symbol && `${ prefix }${ symbol }` ) ; } ; } , } ) ; function reduce < N > ( fn ) { return ( first , ... rest ) => rest . reduce ( fn , first ) ; }