fix(@formatjs/intl-durationformat): use BigDecimal for sub-second rollups#6466
Merged
fix(@formatjs/intl-durationformat): use BigDecimal for sub-second rollups#6466
Conversation
…lups
Sub-second units that roll up into a numeric parent (`milliseconds:
'numeric'`, etc.) were combined with float arithmetic — `1 + 473/1e3`
lands on `1.4729999999999998650`, which `roundingMode: 'trunc'` then
truncated to `1.472999999s` instead of `1.473s`.
Carry the value as BigDecimal end-to-end and pass its decimal string to
NumberFormat. NumberFormat (V3, ES2023) parses the string as a
Mathematical Value, sidestepping the IEEE 754 round-trip entirely.
Also adds `ES2023.Intl` to BASE_TSCONFIG.lib so `formatToParts` accepts
the `${number}` string overload at type-check time.
Fixes #6462
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
longlho
commented
Apr 29, 2026
| }) | ||
| } | ||
| let parts = nf.formatToParts(value) | ||
| let parts = nf.formatToParts(value.toString() as `${number}`) |
Member
Author
There was a problem hiding this comment.
this is lossy, should carry BigDecimal all the way through
Member
Author
There was a problem hiding this comment.
might need to type guard downstream
…rFormat Addresses review feedback on #6466: the previous version round-tripped the BigDecimal through `.toString() as ${number}` before formatToParts, which is conceptually lossy and required a hand-waving cast. NumberFormat (V3) coerces non-primitive inputs through ToPrimitive → toString and parses the result as a StringNumericLiteral, so passing the BigDecimal straight through gives the same exact-decimal semantics with no cast. - Widen `createMemoizedNumberFormat` to a `NumberFormatLike` that types `format`/`formatToParts` as accepting BigDecimal (and string). - Drop the `${number}` cast at the formatToParts call. - Revert the `ES2023.Intl` lib addition — no longer needed now that the call site doesn't depend on the V3 string overload signature. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Member
Author
|
Addressed in 17c55a9 — now passes |
This was referenced Apr 29, 2026
longlho
added a commit
that referenced
this pull request
Apr 29, 2026
…ndency The polyfill bundle imports BigDecimal (added in #6466 for sub-second rollup precision), but @formatjs/bigdecimal was only listed in BUILD.bazel — not in package.json. rolldown externalizes it, so consumers hit "Rolldown failed to resolve import @formatjs/bigdecimal" at build time after updating to 0.10.6. Fixes #6467 Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Sub-second units that roll up into a numeric parent (
milliseconds: 'numeric', etc.) were combined with float arithmetic.1 + 473/1e3lands on1.4729999999999998650, androundingMode: 'trunc'truncated that to1.472999999sinstead of1.473s.Carry the value as
BigDecimalend-to-end and pass its decimal string toNumberFormat. NumberFormat (V3, ES2023) parses the string as a Mathematical Value, sidestepping the IEEE 754 round-trip entirely.Also adds
ES2023.IntltoBASE_TSCONFIG.libsoformatToPartsaccepts the${number}string overload at type-check time.Fixes #6462
Test plan
bazel test //packages/intl-durationformat/...— all 7 tests passbazel test //packages/...— full suite (374 tests) passes; theES2023.Intllib addition didn't break any other package's typecheck🤖 Generated with Claude Code