money.parse
v0.1.0 latestParse a monetary string into a bigint-based Money object with ISO 4217 currency awareness.
Parse a monetary string into a bigint-based Money object with ISO 4217 currency awareness.
Signature
function parse(input: string, opt?: MoneyParseOptions): Money | null
Type Definitions:
MoneyParseOptions— interfaceMoney— interface
Problem
Monetary values from user input, APIs, and databases arrive as strings in diverse formats ("$12.34", "12.34 USD", "1,234.56 EUR"). Using parseFloat() loses precision on edge cases (0.1 + 0.2 !== 0.3). Manual parsing must handle currency extraction, comma stripping, and minor unit conversion.
How It Works
Extracts currency code from the string (or uses the currency option). Converts the numeric portion to bigint minor units for exact representation. Infers scale from decimal places in the input; if no decimal point, uses the currency's minorUnit from @bizkitjs/standards.
Boundaries
- Returns null for empty/whitespace, unparseable, or missing-currency input.
- Throws TypeError for non-string input.
- Decimal separator is always . (period). Commas are stripped as thousand separators.
- Currency symbols ($, €) are stripped; only the 3-letter code is used.
- If no decimal and currency is unknown, defaults to scale=2.
Replaces
Common boilerplate this function replaces:
const amount = Math.round(parseFloat(str) * 100); // loses precision for edge cases
Examples
money.parse("12.34 USD"); // { amount: 1234n, currency: "USD", scale: 2 }
money.parse("1000 JPY"); // { amount: 1000n, currency: "JPY", scale: 0 }
money.parse("1,234.567 BHD"); // { amount: 1234567n, currency: "BHD", scale: 3 }
money.parse("$100", { currency: "USD" }); // { amount: 10000n, currency: "USD", scale: 2 }
money.parse("not money"); // null
Standards
Caveats
- Scale is inferred from decimal places when present (e.g. '12.345' → scale=3), regardless of currency's standard minor unit.
- Only period (.) is recognized as decimal separator. Locales using comma as decimal separator must pre-process.
FAQ
How to parse money strings in JavaScript without precision loss?
money.parse('12.34 USD') returns { amount: 1234n, currency: 'USD', scale: 2 }. Uses bigint for exact representation.
What does the n suffix mean in amount values?
The n suffix denotes BigInt literals in JavaScript. 1234n is a BigInt, not a Number, avoiding IEEE 754 precision issues.
How does money.parse determine the scale?
From decimal places in the input. If no decimal point, uses the currency's ISO 4217 minorUnit (e.g. 2 for USD, 0 for JPY).
Can money.parse handle currency symbols like $ or €?
Symbols are stripped. Use the currency option for explicit currency: money.parse('$100', { currency: 'USD' }).
Why use bigint instead of number for money?
IEEE 754 floating-point cannot represent all decimal fractions exactly (0.1 + 0.2 !== 0.3). BigInt integer arithmetic avoids this.