UNPKG

@etsoo/shared

Version:

TypeScript shared utilities and functions

165 lines (144 loc) 4.13 kB
declare global { interface Number { /** * To the exact precision number avoiding precision lost * @param precision Precision */ toExact(precision?: number): number; /** * To the step number, like 0, 10, 20, 30 for step 10 * @param step Step */ toStep(step: number): number; } } Number.prototype.toExact = function (this: number, precision?: number) { if (precision == null || precision < 0) precision = 2; if (precision === 0) return Math.round(this); const p = Math.pow(10, precision); return Math.round(this * p) / p; }; Number.prototype.toStep = function (this: number, step: number) { if (step <= 0) return this; return Math.floor(this / step) * step; }; export namespace NumberUtils { /** * Format number * @param input Input * @param locale Locale * @param options Options * @returns Result */ export function format( input: number | bigint, locale?: string | string[], options?: Intl.NumberFormatOptions ) { // Formatter const intl = new Intl.NumberFormat(locale, options); return intl.format(input); } /** * Format money * @param input Input * @param currency Currency, like USD for US dollar * @param locale Locale * @param isInteger Is integer value * @param options Options * @returns Result */ export function formatMoney( input: number | bigint, currency?: string, locale?: string | string[], isInteger: boolean = false, options: Intl.NumberFormatOptions = {} ) { if (currency) { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat options.style = "currency"; options.currency = currency; options.currencyDisplay ??= "narrowSymbol"; } if (isInteger) { options.minimumFractionDigits ??= 0; options.maximumFractionDigits ??= 0; } else options.minimumFractionDigits ??= 2; return format(input, locale, options); } /** * Format file size * @param size File size * @param fractionDigits Fraction digits * @returns Result */ export function formatFileSize(size: number, fractionDigits: number = 2) { const i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024)); return ( (size / Math.pow(1024, i)).toFixed(fractionDigits) + " " + ["B", "KB", "MB", "GB", "TB", "PB"][i] ); } /** * Get currency symbol or name from ISO code * @param code ISO currency code, like USD / CNY * @param display Display format * @param locale Locale * @returns Result */ export function getCurrencySymbol( code: string, display: "symbol" | "narrowSymbol" | "name" = "narrowSymbol", locale?: string ): string | undefined { const formatter = new Intl.NumberFormat(locale, { style: "currency", currency: code, currencyDisplay: display }); const parts = formatter.formatToParts(); const symbol = parts.find((part) => part.type === "currency")?.value; return symbol; } /** * Parse number * @param rawData Raw data */ export function parse(rawData: unknown): number | undefined; /** * Parse number with default value * @param rawData Raw data * @param defaultValue Default value */ export function parse(rawData: unknown, defaultValue: number): number; export function parse( rawData: unknown, defaultValue?: number ): number | undefined { if (rawData == null || rawData === "") { return defaultValue; } if (typeof rawData === "number") { if (isNaN(rawData)) return defaultValue; return rawData; } const p = parseFloat(rawData.toString()); if (isNaN(p)) return defaultValue; return p; } /** * Parse float value and unit * @param input Input string * @returns Result, like [number, string] */ export const parseWithUnit = ( input: string ): [number, string] | undefined => { if (/^(\d+)(\D*)$/g.test(input)) { return [Number(RegExp.$1), RegExp.$2.trim()]; } return undefined; }; }