From a792f264acdd7f2e8209fa92be3313bb8efabe68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Connor=20B=C3=A4r?= Date: Wed, 29 Jul 2020 09:01:59 +0200 Subject: [PATCH] fix: check support for Intl ahead of time --- src/base.ts | 53 ++++++++++++++++++++++++++++++------------------- src/lib/intl.ts | 15 ++++++++++++-- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/base.ts b/src/base.ts index 9b11df9..7539e72 100644 --- a/src/base.ts +++ b/src/base.ts @@ -17,7 +17,7 @@ import { Locale, Options, Format } from './types'; import { isNumberFormatSupported, isNumberFormatToPartsSupported, - getNumberFormat, + memoizeIntl, } from './lib/intl'; import { findIndex } from './lib/findIndex'; @@ -28,12 +28,17 @@ type GetOptions = ( ...args: T ) => Options; -export function formatFactory(getOptions: GetOptions) { - return (value: number, locales?: Locale | Locale[], ...args: T): string => { - if (!isNumberFormatSupported) { - return `${value}`; - } +export function formatFactory( + getOptions: GetOptions, +): (value: number, locales?: Locale | Locale[], ...args: T) => string { + if (!isNumberFormatSupported) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + return (value, _locales, ..._args): string => `${value}`; + } + + const getNumberFormat = memoizeIntl(); + return (value, locales, ...args): string => { const options = getOptions(locales, ...args); const numberFormat = getNumberFormat(locales, options); return numberFormat.format(value); @@ -42,16 +47,21 @@ export function formatFactory(getOptions: GetOptions) { export function formatToPartsFactory( getOptions: GetOptions, -) { - return ( - value: number, - locales?: Locale | Locale[], - ...args: T - ): Intl.NumberFormatPart[] => { - if (!isNumberFormatToPartsSupported) { - return [{ type: 'integer', value: value.toString() }]; - } +): ( + value: number, + locales?: Locale | Locale[], + ...args: T +) => Intl.NumberFormatPart[] { + if (!isNumberFormatToPartsSupported) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + return (value, _locales, ..._args): Intl.NumberFormatPart[] => [ + { type: 'integer', value: value.toString() }, + ]; + } + + const getNumberFormat = memoizeIntl(); + return (value, locales, ...args): Intl.NumberFormatPart[] => { const options = getOptions(locales, ...args); const numberFormat = getNumberFormat(locales, options); return numberFormat.formatToParts(value); @@ -66,12 +76,15 @@ function getPart(parts: Intl.NumberFormatPart[], name: string): string { export function resolveFormatFactory( getOptions: GetOptions, -) { - return (locales?: Locale | Locale[], ...args: T): Format | null => { - if (!isNumberFormatToPartsSupported) { - return null; - } +): (locales?: Locale | Locale[], ...args: T) => null | Format { + if (!isNumberFormatToPartsSupported) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + return (_locales, ..._args) => null; + } + + const getNumberFormat = memoizeIntl(); + return (locales, ...args): Format => { const options = getOptions(locales, ...args); const numberFormat = getNumberFormat(locales, options); const resolvedOptions = numberFormat.resolvedOptions(); diff --git a/src/lib/intl.ts b/src/lib/intl.ts index f6af66f..83207dd 100644 --- a/src/lib/intl.ts +++ b/src/lib/intl.ts @@ -61,15 +61,26 @@ export const isIntlSupported = (() => { return isNumberFormatSupported; })(); -export const getNumberFormat: ( +let memoizedIntl: ( locales?: Locale | Locale[], options?: Intl.NumberFormatOptions, -) => Intl.NumberFormat = memoizeFormatConstructor(Intl.NumberFormat); +) => Intl.NumberFormat; + +export const memoizeIntl: () => ( + locales?: Locale | Locale[], + options?: Intl.NumberFormatOptions, +) => Intl.NumberFormat = () => { + if (!memoizedIntl) { + memoizedIntl = memoizeFormatConstructor(Intl.NumberFormat); + } + return memoizedIntl; +}; export function resolveLocale(locales?: Locale | Locale[]): Locale | Locale[] { if (locales && locales.length >= 0) { return locales; } + const getNumberFormat = memoizeIntl(); const numberFormat = getNumberFormat(); return numberFormat.resolvedOptions().locale; }