amannn / next-intl

šŸŒ Internationalization (i18n) for Next.js
https://next-intl-docs.vercel.app
MIT License
2.63k stars 236 forks source link

Allow formatting of number strings #1492

Open sohrab- opened 3 weeks ago

sohrab- commented 3 weeks ago

Is your feature request related to a problem? Please describe.

The number formatter in this package allows number or bigint input only.

When working with very larger numbers, we typically use other libraries that can deal with high precision. However, in order to use next-intl number formatter, we have to turn those numbers back into native number values, which would be lossy and produce incorrect values.

Describe the solution you'd like

Intl.NumberFormat already supports a string param that it can then format losslessly in modern browsers. Seeing how we delegate to this library anyway, it would be good to broaden the type of number() function.

This way we can pass large numbers as string to the formatter and get a correct representation out.

Describe alternatives you've considered

My workaround is to just get the locale and do my own Intl.NumberFormat formatter. But then I have to forego or re-implement all the nice locale-awareness and caching that next-intl has already got.

amannn commented 3 weeks ago

Interesting, could definitely be worth consideringā€”thanks for the report!

This will need some investigation first, e.g.:

  1. Check if intl-messageformat supports strings for numbers in messages. We had a similar story with allowing date strings in format.dateTime(ā€¦) (see https://github.com/amannn/next-intl/pull/758#discussion_r1609624363), which unfortunately had to be delayed for the time being.
  2. Verify browser and server runtimes support for string params.
sohrab- commented 1 week ago

Browser and runtime support seem decent (except Deno):

image

intl-messageformat, or rather intl-numberformat does seem to only support number atm. I asked the question over there as well: https://github.com/formatjs/formatjs/discussions/4699

amannn commented 5 days ago

One implication of this in combination with https://github.com/amannn/next-intl/pull/1499 would be that we can currently do this (ref):

"{count} followers"
// ^? {count: string}

"{count, number} followers"
// ^? {count: number}

That helps to make sure you're using the number formatter when passing a number.

If we allow numbers as strings, we'd allow number | string for the number formatter. Note that we can still keep the validation for not allowing to pass a number to simple params.

amannn commented 5 days ago

A note from https://x.com/SlexAxton/status/1859242191408746751 on support of string-based numbers in Format.JS:

it does support them i think, just the types are wrong

Might be worth checking if this is something we could safely use.