import { ReduceOptions } from './reduceoptions' ; template T template R param { Iterable < T > } source param { ReduceOptions < T , R > } options returns { R } export function reduce < T , R = T > ( source , options ) ; export function reduce < T , R = T > ( source , accumulator , seed ? ) ; export function reduce < T , R = T > ( source , optionsOrAccumulator , seed ? ) { const options = typeof optionsOrAccumulator === 'function' ? arguments . length > 2 ? { 'callback' : optionsOrAccumulator , 'seed' : seed } : { 'callback' : optionsOrAccumulator } : optionsOrAccumulator ; const { [ 'seed' ] : _seed , [ 'callback' ] : callback } = options ; const hasSeed = options . hasOwnProperty ( 'seed' ) ; let i = 0 ; let hasValue = false ; let acc = _seed as T | R ; for ( const item of source ) { if ( hasValue || ( hasValue = hasSeed ) ) { acc = callback ( < R > acc , item , i ++ ) ; } else { acc = item ; hasValue = true ; i ++ ; } } if ( ! ( hasSeed || hasValue ) ) { throw new Error ( 'Sequence contains no elements' ) ; } return acc as R ; }