calculator2026/src/lib/decimal.ts
2026-03-12 12:02:05 +08:00

44 lines
1.2 KiB
TypeScript

import Decimal from 'decimal.js'
import { isFiniteNumber } from '@/lib/number'
type MaybeNumber = number | null | undefined
type DecimalInput = Decimal.Value
export const toDecimal = (value: DecimalInput) => new Decimal(value)
export const roundTo = (value: DecimalInput, decimalPlaces = 2) =>
new Decimal(value).toDecimalPlaces(decimalPlaces, Decimal.ROUND_HALF_UP).toNumber()
const sumFiniteValues = (values: Iterable<unknown>) => {
let total = new Decimal(0)
for (const value of values) {
if (!isFiniteNumber(value)) continue
total = total.plus(value)
}
return total.toNumber()
}
export const addNumbers = (...values: MaybeNumber[]) => sumFiniteValues(values)
export const sumByNumber = <T>(list: T[], pick: (item: T) => MaybeNumber) => {
let total = new Decimal(0)
for (const item of list) {
const value = pick(item)
if (!isFiniteNumber(value)) continue
total = total.plus(value)
}
return total.toNumber()
}
export const decimalAggSum = (params: { values?: unknown[] }) => {
const values = params.values || []
let hasFinite = false
for (const value of values) {
if (!isFiniteNumber(value)) continue
hasFinite = true
break
}
if (!hasFinite) return null
return sumFiniteValues(values)
}