packages/intl-supportedvaluesof/README.md
Polyfill for Intl.supportedValuesOf()
This package implements the ECMA-402 Intl.supportedValuesOf() specification:
npm install @formatjs/intl-supportedvaluesof
Import the polyfill to make Intl.supportedValuesOf available globally:
import '@formatjs/intl-supportedvaluesof/polyfill'
// Now available on the global Intl object
const calendars = Intl.supportedValuesOf('calendar')
// ['buddhist', 'chinese', 'coptic', 'dangi', 'ethioaa', 'ethiopic', 'gregory', ...]
const currencies = Intl.supportedValuesOf('currency')
// ['AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', ...]
const timeZones = Intl.supportedValuesOf('timeZone')
// ['Africa/Abidjan', 'Africa/Accra', ..., 'Pacific/Wallis']
Import the function directly without modifying the global namespace:
import {supportedValuesOf} from '@formatjs/intl-supportedvaluesof'
const numberingSystems = supportedValuesOf('numberingSystem')
// ['adlm', 'ahom', 'arab', 'arabext', 'bali', 'beng', 'bhks', ...]
const units = supportedValuesOf('unit')
// ['acre', 'bit', 'byte', 'celsius', 'centimeter', 'day', 'degree', ...]
The function accepts one of six string keys and returns an array of supported values:
| Key | Returns | Example Values |
|---|---|---|
'calendar' | Supported calendar systems | 'gregory', 'islamic', 'buddhist', 'chinese' |
'collation' | Supported collation algorithms | 'emoji', 'eor', 'phonebk', 'search' |
'currency' | Supported ISO 4217 currency codes | 'USD', 'EUR', 'JPY', 'GBP' |
'numberingSystem' | Supported numbering systems | 'arab', 'latn', 'hanidec', 'thai' |
'timeZone' | Supported IANA time zones | 'America/New_York', 'Europe/London', 'Asia/Tokyo' |
'unit' | Supported measurement units | 'meter', 'celsius', 'liter', 'acre' |
supportedValuesOf(key: string): string[]Returns an array of supported values for the given key.
Parameters:
key - One of: 'calendar', 'collation', 'currency', 'numberingSystem', 'timeZone', 'unit'Returns:
Throws:
RangeError - If the key is not one of the supported valuesExample:
import {supportedValuesOf} from '@formatjs/intl-supportedvaluesof'
// Valid usage
const calendars = supportedValuesOf('calendar')
console.log(calendars) // ['buddhist', 'chinese', 'coptic', ...]
// Invalid key throws RangeError
try {
supportedValuesOf('invalid')
} catch (e) {
console.error(e) // RangeError: Invalid key: invalid
}
This polyfill dynamically validates candidate values against the actual Intl implementation rather than maintaining static lists. This approach ensures:
For each category, the implementation:
Intl formatter with that value// Implementation tests if a calendar is supported:
function isSupportedCalendar(calendar) {
try {
// Attempt to create DateTimeFormat with this calendar
const formatter = new Intl.DateTimeFormat(`en-u-ca-${calendar}`)
// Verify the calendar was actually accepted
const resolvedOptions = formatter.resolvedOptions()
return resolvedOptions.calendar === calendar
} catch {
return false
}
}
This ensures that only calendars actually supported by your runtime are returned, not just a static list.
This package includes TypeScript type definitions. When using as a polyfill, the global Intl namespace is automatically augmented:
import '@formatjs/intl-supportedvaluesof/polyfill'
// TypeScript knows about Intl.supportedValuesOf
const calendars: string[] = Intl.supportedValuesOf('calendar')
// TypeScript will error on invalid keys
Intl.supportedValuesOf('invalid') // Error: Argument of type '"invalid"' is not assignable...
This polyfill is only needed for older browsers that don't have native support for Intl.supportedValuesOf(). Native support is available in:
The polyfill requires the following Intl APIs to be available:
Intl.DateTimeFormat (for calendar, timeZone, numberingSystem)Intl.NumberFormat (for currency, unit, numberingSystem)Intl.Collator (for collation)locale parameterv2.x and earlier had a non-standard optional locale parameter that filtered results by locale. This has been removed to match the ECMA-402 specification.
// ❌ v2.x (non-standard, no longer works)
const calendars = supportedValuesOf('calendar', 'en-US')
// ✅ v3.0 (spec-compliant)
const calendars = supportedValuesOf('calendar')
The function now always returns ALL supported values, matching native browser behavior.
If you need locale-specific filtering in v3.0+, implement it yourself:
import {supportedValuesOf} from '@formatjs/intl-supportedvaluesof'
// Get all supported calendars
const allCalendars = supportedValuesOf('calendar')
// Filter by what a specific locale actually uses/accepts
const enUSCalendars = allCalendars.filter(calendar => {
try {
const formatter = new Intl.DateTimeFormat('en-US', {calendar})
return formatter.resolvedOptions().calendar === calendar
} catch {
return false
}
})
However, note that most use cases don't need locale-specific filtering, as the spec's design returns all values that any locale could use.
import {supportedValuesOf} from '@formatjs/intl-supportedvaluesof'
const calendars = supportedValuesOf('calendar')
if (calendars.includes('islamic')) {
console.log('Islamic calendar is supported')
const formatter = new Intl.DateTimeFormat('en-US', {calendar: 'islamic'})
console.log(formatter.format(new Date()))
}
import {supportedValuesOf} from '@formatjs/intl-supportedvaluesof'
const currencies = supportedValuesOf('currency')
console.log(`This runtime supports ${currencies.length} currencies:`)
currencies.forEach(currency => {
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency,
})
console.log(`${currency}: ${formatter.format(100)}`)
})
import {supportedValuesOf} from '@formatjs/intl-supportedvaluesof'
function isValidTimeZone(timeZone) {
const supportedTimeZones = supportedValuesOf('timeZone')
return supportedTimeZones.includes(timeZone)
}
console.log(isValidTimeZone('America/New_York')) // true
console.log(isValidTimeZone('Invalid/TimeZone')) // false
MIT