Skip to content

API Overview

SymbolPurposeExecutionCommon gotcha
moneyConstruct validated moneySyncBigint requires { unit: 'minor' }
currencyResolve supported definitionSyncUnknown codes throw
defineCurrencyDefine an explicit scaleSyncCode must be three uppercase letters
add / subtractCombine matching currenciesSyncMismatches throw
multiply / divideExact decimal scalingSyncUse decimal strings
sumAggregate with identity currencySyncPass { currency }
allocateSplit without losing minor unitsSyncWeights must be non-negative
exchangeConvert through an exact rateSyncRate source must match value currency
formatPresent money with IntlSyncFormatting does not define currency scale
toJSON / parseMoneyJSONCross JSON boundarySyncPersisted amount uses minor units

Package Entry Point

ImportPurpose
@vielzeug/coinsComplete public Coins API

Construction

currency / defineCurrency

ts
currency(code: string): Currency
defineCurrency({ code, minorUnit }): Currency

Built-ins: USD, EUR, GBP, JPY, KRW, BHD, KWD.

money

ts
money(amount: string, currency: Currency): Money
money(amount: string, currency: Currency, options: { rounding: RoundingMode }): Money
money(amount: bigint, currency: Currency, options: { unit: 'minor' }): Money
ts
money('19.99', USD);
money(1999n, USD, { unit: 'minor' });

decimal

ts
decimal(value: string): Decimal

Creates an exact rational value for multiplication, division, or exchange rates.

Arithmetic

ts
add(left, right)
subtract(left, right)
multiply(value, factor, { rounding? })
divide(value, divisor, { rounding? })
compare(left, right)
abs(value)
negate(value)
round(value, { fractionDigits, rounding? })

factor and divisor are decimal strings. Matching currency is required for binary money operations.

Aggregation

ts
sum(values, { currency })
allocate(value, count)
allocate(value, weights)
clamp(value, { min, max })

sum([], { currency: USD }) returns zero USD. allocate returns values whose minor-unit total exactly equals input.

Exchange

ts
exchangeRate({ from, to, value }): ExchangeRate
exchange(value, rate, { rounding? }): Money
ts
const rate = exchangeRate({ from: USD, to: EUR, value: '0.9234' });
exchange(money('100.00', USD), rate);

Formatting

ts
format(value, options?): string
formatParts(value, options?): MoneyFormatPart[]

FormatOptions uses locale, style, minimumFractionDigits, and maximumFractionDigits.

Serialization

ts
toDecimal(value): string
toJSON(value): MoneyJSON
parseMoneyJSON(value: unknown, options?: { currency?: (code: string) => Currency }): Money
parseMoney(value: unknown): Money
isMoney(value: unknown): value is Money

Types

ts
type Currency = { code: CurrencyCode; minorUnit: number };
type Money = { amount: bigint; currency: Currency };
type Decimal = { numerator: bigint; denominator: bigint };
type ExchangeRate = { from: Currency; to: Currency; value: Decimal };
type MoneyJSON = { amount: string; currency: string; unit: 'minor' };
type RoundingMode = 'awayFromZero' | 'ceil' | 'floor' | 'halfAwayFromZero' | 'halfEven' | 'towardZero';

Errors

Every Coins failure extends CoinsError and exposes code.

  • INVALID_CURRENCY
  • INVALID_DECIMAL
  • INVALID_MONEY
  • INVALID_ALLOCATION
  • INVALID_ROUNDING
  • DIVISION_BY_ZERO
  • CURRENCY_MISMATCH

CurrencyMismatchError and InvalidCurrencyError are specialized CoinsError subclasses.