export type GridAggregationFunction = ( values: T[] ) => R | null function isNumber(value: unknown): value is number { return typeof value === 'number' && !Number.isNaN(value) } export const sum: GridAggregationFunction = (values) => { let sum = 0 for (const value of values) { if (isNumber(value)) { sum += value } } return sum } export const avg: GridAggregationFunction = (values) => { if (values.length === 0) { return null } let sum = 0 let valuesCount = 0 for (const value of values) { if (isNumber(value)) { valuesCount += 1 sum += value } } return sum / valuesCount } export const min: GridAggregationFunction< number | Date, number | Date | null > = (values) => { if (values.length === 0) { return null } let min: number | Date = +Infinity for (const value of values) { if (value != null && value < min) { min = value } } return min } export const max: GridAggregationFunction< number | Date, number | Date | null > = (values) => { if (values.length === 0) { return null } let max: number | Date = -Infinity for (const value of values) { if (value != null && value > max) { max = value } } return max } export const size: GridAggregationFunction = ( values ) => values.filter((value) => value != null).length export const AGGREGATION_FUNCTIONS = { sum, avg, min, max, size, }