Skip to content

fix: improve type of values accepted by date/time/number formats#2359

Merged
andrii-bodnar merged 1 commit intolingui:mainfrom
YarnSphere:main
Nov 11, 2025
Merged

fix: improve type of values accepted by date/time/number formats#2359
andrii-bodnar merged 1 commit intolingui:mainfrom
YarnSphere:main

Conversation

@YarnSphere
Copy link
Copy Markdown
Contributor

@YarnSphere YarnSphere commented Oct 30, 2025

Description

Modern ES versions support more types of values when calling Intl.(DateTime|Number)Format.prototype.format than those allowed by Lingui:

This commit uses the types defined by TypeScript directly, rather than ad hoc types, which depend on the TypeScript target configured by the user, allowing users to pass to date and number any values that are supported by Intl.(DateTime|Number)Format.prototype.format.

Example of code that currently fails to type check (even though it runs correctly):

i18n.date(999999999999);
i18n.number(99n);
i18n.number("99.9");

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Examples update

Fixes # (issue)

Checklist

  • I have read the CONTRIBUTING and CODE_OF_CONDUCT docs
  • I have added tests that prove my fix is effective or that my feature works
  • I have added the necessary documentation (if appropriate)

@vercel
Copy link
Copy Markdown

vercel Bot commented Oct 30, 2025

@YarnSphere is attempting to deploy a commit to the Crowdin Team on Vercel.

A member of the Team first needs to authorize it.

Comment thread packages/core/src/i18n.ts Outdated
t: I18n["_"] = this._.bind(this)

date(value: string | Date, format?: Intl.DateTimeFormatOptions): string {
date(value?: string | DateTimeFormatValue, format?: Intl.DateTimeFormatOptions): string {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why value here become optional?

Does the DateTimeFormatValue already include a string?

Copy link
Copy Markdown
Contributor Author

@YarnSphere YarnSphere Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why value here become optional?

I made it optional simply because it's supported, when the value is undefined, it returns the current date. Try out: new Intl.DateTimeFormat().format() (should return the current date), which should be similar to calling i18n.date().

Let me know if you'd prefer it to not be optional, but note that it would still work in JavaScript, it simply wouldn't type check anymore.

Does the DateTimeFormatValue already include a string?

No, see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/format#parameters (yet it does support numbers, even though MDN doesn't mention it).


By the way, you can test the changes in the Lingui repository itself just be changing the "target": "es2017" to something more modern in the root tsconfig.json (e.g., "target": "ESNext").

Copy link
Copy Markdown
Contributor Author

@YarnSphere YarnSphere Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to give you a little bit more context: with ESNext, the latest Intl.(DateTime|Number)Format.prototype.format types are the following (omitting all non-relevant definitions):

declare namespace Intl {
    // Defined in `lib.es5.d.ts`:
    interface DateTimeFormat {
        format(date?: Date | number): string;
        // ...
    }

    // Defined in `lib.es2023.intl.d.ts`:
    type StringNumericLiteral = `${number}` | "Infinity" | "-Infinity" | "+Infinity";
    interface NumberFormat {
        format(value: number | bigint | StringNumericLiteral): string;
        // ...
    }
}

I believe Temporal isn't yet supported (this will most likely change in the future), and this PR should make it so that Lingui supports Temporal as soon as the TypeScript ES lib types are updated to support it.

Also, note that the date in DateTimeFormat.prototype.format is optional (as opposed to the NumberFormat.prototype.format value), which is why I changed Lingui's i18n.date's value to be optional. Hope this helps. :)

Modern ES versions support more types of values when calling
`Intl.(DateTime|Number)Format.prototype.format`:
- Datetime formatting nowadays supports `Temporal` values (see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/format#parameters);
- Number formatting nowadays supports `BigInt`s and strings (see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/format#parameters).

This commit uses the types defined by TypeScript directly, rather than ad hoc types, which
depend on the TypeScript target configured by the user.
@YarnSphere
Copy link
Copy Markdown
Contributor Author

YarnSphere commented Nov 3, 2025

Fixed Prettier issues in latest push.

@codecov
Copy link
Copy Markdown

codecov Bot commented Nov 4, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.27%. Comparing base (6bb8983) to head (c4314c9).
⚠️ Report is 232 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2359      +/-   ##
==========================================
- Coverage   77.05%   76.27%   -0.78%     
==========================================
  Files          84       99      +15     
  Lines        2157     2651     +494     
  Branches      555      692     +137     
==========================================
+ Hits         1662     2022     +360     
- Misses        382      505     +123     
- Partials      113      124      +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@vercel
Copy link
Copy Markdown

vercel Bot commented Nov 11, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
js-lingui Ready Ready Preview Nov 11, 2025 1:15pm

@andrii-bodnar andrii-bodnar merged commit c1f2800 into lingui:main Nov 11, 2025
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants