idr-formatting
Version:
Tiny helpers to format and parse Indonesian-style prices (IDR) with '.' thousands and ',' decimals.
69 lines (67 loc) • 2.51 kB
text/typescript
/** Sign type for fixed-point representation */
type IdxSign = 1 | -1;
/** Exact fixed-point representation backed by BigInt (no floating-point errors) */
interface FixedIdr {
/** Sign of the value: 1 or -1 */
sign: IdxSign;
/** All digits as integer (no decimal point) */
units: bigint;
/** Number of decimal digits */
scale: number;
/** Convert to JS Number (may lose precision for very large values) */
toNumber(): number;
/** Canonical decimal string with "." as decimal separator */
toString(): string;
}
interface ParseIdrOptions {
/** "number" (default) -> returns number|null; "fixed" -> returns FixedIdr|null */
mode?: "number" | "fixed";
}
interface FormatIdrOptions {
/**
* Decimal behavior
* - "auto" (default): preserve decimals as typed (no rounding, no padding)
* - number: force exactly that many decimals (round/pad as needed)
*/
decimals?: "auto" | number;
/**
* When decimals === "auto", pad decimals with zeros to at least 2 digits.
* Example: "1050,5" -> "1.050,50"
*/
padZeros?: boolean;
}
/**
* Format a value into Indonesian numeric style:
* - Thousands: "."
* - Decimals: ","
*
* Heuristics:
* - If comma (",") exists → it is the decimal separator.
* - If dot (".") exists and no comma:
* • If pattern looks like thousands (e.g., "1.500", "12.345.678"),
* treat "." as thousands.
* • Otherwise, first dot is decimal (e.g., "12.34" → "12,34").
* - Plain digits are formatted with thousand separators.
* - Minus sign is preserved.
*
* Notes:
* - Non-digit characters are ignored (currency symbol, letters, spaces).
* - Decimal digits are preserved as typed unless `decimals` option is set.
*/
declare function formatIdr(value: string | number | FixedIdr | null | undefined, options?: FormatIdrOptions): string;
/**
* Parse an Indonesian-formatted string into a JS number or FixedIdr.
*
* Rules:
* - "." is thousands separator, removed.
* - "," is decimal, converted to ".".
* - Only the first comma is kept as decimal.
* - Minus sign is preserved.
* - Returns null for invalid input.
*
* Modes:
* - "number" (default): return JS Number (may lose precision).
* - "fixed": return FixedIdr with BigInt units (exact).
*/
declare function parseIdr(str: string | number | null | undefined, opts?: ParseIdrOptions): number | FixedIdr | null;
export { type FixedIdr, type FormatIdrOptions, type IdxSign, type ParseIdrOptions, formatIdr, parseIdr };