Skip to content

feat: support typed message IDs#2503

Open
mrmckeb wants to merge 3 commits intolingui:mainfrom
mrmckeb:next
Open

feat: support typed message IDs#2503
mrmckeb wants to merge 3 commits intolingui:mainfrom
mrmckeb:next

Conversation

@mrmckeb
Copy link
Copy Markdown

@mrmckeb mrmckeb commented Apr 9, 2026

Description

Adds support for optionally typed message IDs, for build systems where the message IDs are known ahead of time.

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 #2478

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 Apr 9, 2026

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

A member of the Team first needs to authorize it.

export function plural(
value: number | string | LabeledExpression<number | string>,
options: ChoiceOptions
options: ChoiceOptions,
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I investigated this change, which happened on save. This is the default in Prettier now, it's likely that this file hasn't been formatted for a while. I can revert if this change is an issue.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 9, 2026

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

Project Deployment Actions Updated (UTC)
js-lingui Ready Ready Preview Apr 29, 2026 0:17am

Request Review

@andrii-bodnar andrii-bodnar changed the title Support typed message IDs feat: support typed message IDs Apr 9, 2026
Copy link
Copy Markdown
Contributor

@andrii-bodnar andrii-bodnar left a comment

Choose a reason for hiding this comment

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

@mrmckeb thank you for the contribution! Please check the failed CI/CD pipeline.

Additionally, could we include a reference to the new guide in the Explicit vs Generated IDs article? This would improve the discoverability of the new feature.

@mrmckeb
Copy link
Copy Markdown
Author

mrmckeb commented Apr 12, 2026

Thanks @andrii-bodnar, I've just pushed up those changes.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.01%. Comparing base (dd43fb0) to head (53cb55a).
⚠️ Report is 334 commits behind head on next.

Additional details and impacted files
@@             Coverage Diff             @@
##             next    #2503       +/-   ##
===========================================
+ Coverage   76.66%   89.01%   +12.35%     
===========================================
  Files          81      118       +37     
  Lines        2083     3315     +1232     
  Branches      532      978      +446     
===========================================
+ Hits         1597     2951     +1354     
+ Misses        375      329       -46     
+ Partials      111       35       -76     

☔ 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.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an opt-in TypeScript mechanism for typed message IDs across Lingui packages, enabling autocomplete and compile-time validation when IDs are known ahead of time (via module augmentation).

Changes:

  • Introduces Register module-augmentation hook and MessageId type in @lingui/core, and wires it into core/react/macro typings.
  • Adds/extends type-tests to validate both the default (MessageId = string) and augmented (union) behavior.
  • Documents the feature and adds it to the website sidebar.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
website/sidebars.ts Adds “Typed Message IDs” to the Advanced docs sidebar.
website/docs/guides/typed-message-ids.md New guide explaining how to opt into typed IDs via module augmentation.
website/docs/guides/explicit-vs-generated-ids.md Adds a tip linking explicit IDs to the new typed-IDs guide.
tstyche.config.json Expands test glob to include nested __typetests__ directories.
packages/react/src/TransNoContext.tsx Narrows id props from string to MessageId.
packages/react/macro/index.d.mts Updates macro prop types to use MessageId.
packages/core/tsconfig.json Excludes the typed-ids typetest project from core’s tsc --noEmit run.
packages/core/src/index.ts Re-exports MessageId and Register types from @lingui/core.
packages/core/src/i18n.ts Adds Register/MessageId and applies MessageId to MessageDescriptor, events, and i18n._ overloads.
packages/core/macro/index.d.mts Updates macro descriptor id typing to MessageId.
packages/core/typetests/typed-ids/tsconfig.json New typetest tsconfig for the typed-ids augmentation scenario.
packages/core/typetests/typed-ids/lingui.d.ts Provides module augmentation used by typed-ids typetests.
packages/core/typetests/typed-ids/index.tst.ts Asserts typed-ids behavior (valid/invalid IDs) under augmentation.
packages/core/typetests/index.tst.ts Asserts default behavior (MessageId resolves to string without augmentation).
Comments suppressed due to low confidence (1)

packages/core/src/i18n.ts:78

  • MissingHandler still types the callback as (locale: string, id: string) => string, which prevents the new typed MessageId union from flowing into the public missing handler API. Consider changing the callback signature to use id: MessageId so consumers get the same compile-time validation/autocomplete when implementing missing handlers (it still resolves to string when not augmented).
export type MissingMessageEvent = {
  locale: Locale
  id: MessageId
}

type MissingHandler = string | ((locale: string, id: string) => string)


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/core/__typetests__/typed-ids/tsconfig.json
Comment thread website/docs/guides/explicit-vs-generated-ids.md Outdated
Copy link
Copy Markdown
Contributor

@andrii-bodnar andrii-bodnar left a comment

Choose a reason for hiding this comment

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

Looks good to me! @timofei-iatsenko, please also take a look

@andrii-bodnar andrii-bodnar removed this from the v6 milestone Apr 17, 2026
@mrmckeb
Copy link
Copy Markdown
Author

mrmckeb commented Apr 23, 2026

Hey team, did you need anything from me on the PR at this stage? Thanks!

@andrii-bodnar
Copy link
Copy Markdown
Contributor

Hi @mrmckeb, there are some conflicts in this PR, could you please rebase the branch? Please note, the main branch is renamed from what was next previously, you may need some additional fixes in git

@mrmckeb
Copy link
Copy Markdown
Author

mrmckeb commented Apr 29, 2026

Hi @andrii-bodnar, that's now done - I've rebased and pushed that up. Thanks again!

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.

Support typed IDs

3 participants