Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type-safe arguments #410

Open
amannn opened this issue Jul 20, 2023 · 8 comments · May be fixed by #1412
Open

Type-safe arguments #410

amannn opened this issue Jul 20, 2023 · 8 comments · May be fixed by #1412
Labels
area: ergonomics enhancement New feature or request

Comments

@amannn
Copy link
Owner

amannn commented Jul 20, 2023

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

next-intl provides opt-in strict typing for messages. With some additional TypeScript voodoo, it might be possible to support type checking for arguments that need to be passed to t calls.

Resources:

Describe the solution you'd like

{
  "hello": "Hello {name}"
}
t('hello') // Should be an error

We have to evaluate though what it takes to support everything from ICU and also rich text.

Also we should be sure about the performance implications of this (see also #792).

Open question: Since we support defaultTranslationValues, type-safety would only cover types (ie. accept only strings, numbers, etc), but not if an argument is provided or not (it could come from the defaults). This begs the question if defaultTranslationValues are really a good idea or if we should get rid of this. #611 discusses a separate issue but also comes to the conclusion that defaultTranslationValues might be helpful to remove—an alternative is suggested there too.

Describe alternatives you've considered

Not introducing types for this

@amannn amannn added enhancement New feature or request unconfirmed Needs triage. and removed unconfirmed Needs triage. labels Jul 20, 2023
@DemianParkhomenko
Copy link

It would be an extremely useful feature that speeds up the development)

@TommySorensen
Copy link

@amannn I guess this will also help with having different objects of translations for each locale? Currently i load my translations async, but one locale might have more and different translations then the rest.

@matannahmani
Copy link

any updates on this one?

@loczek
Copy link

loczek commented Dec 16, 2023

You can add a global.d.ts file in the root of your project and it should work

type Messages = typeof import("./messages/en.json");
declare interface IntlMessages extends Messages {}

@DemianParkhomenko
Copy link

You can add a global.d.ts file in the root of your project and it should work

type Messages = typeof import("./messages/en.json");
declare interface IntlMessages extends Messages {}

But it does not check arguments, isn't it? i.e. {name} in the example

{
  "hello": "Hello {name}"
}

@ScreamZ
Copy link

ScreamZ commented May 3, 2024

You can add a global.d.ts file in the root of your project and it should work

type Messages = typeof import("./messages/en.json");
declare interface IntlMessages extends Messages {}

But it does not check arguments, isn't it? i.e. {name} in the example

{
  "hello": "Hello {name}"
}

No it doesn't, as the creator said this requires typescript vodoooooo, you need to use template literal parsing with some kind of recursivity and this might happen. That's a nice first contribution to do.

amannn added a commit that referenced this issue Oct 11, 2024
`defaultTranslationValues` allow to share global values to be used in
messages across your app. The most common case are shared rich text
elements (e.g. `b: (chunks) => <b>{chunks}</b>`).

However, over time this feature has shown drawbacks:
1. We can't serialize them automatically across the RSC boundary (see
#611)
2. They get in the way of type-safe arguments (see
#410)

Due to this, the feature will be deprecated and the docs will suggest a
better alternative for common tags in rich text that doesn't have the
limitations mentioned above ([updated
docs](https://next-intl-docs-git-feat-deprecate-defaulttrans-f52ebe-next-intl.vercel.app/docs/usage/messages#rich-text-reuse-tags)).
Shared values don't get a direct replacement from `next-intl`, but
should be handled as part of your app logic (e.g. a shared module, React
Context, etc.).

**Note**: #410 can not be
implemented immediately as part of this, as long as
`defaultTranslationValues` are still available (even if deprecated).
Instead, this feature could be added as part of the next major release.

Contributes to #611
@amannn
Copy link
Owner Author

amannn commented Nov 5, 2024

This is coming in next-intl@4! (see #1499)

@DemianParkhomenko
Copy link

Awesome! Great work

amannn added a commit that referenced this issue Nov 7, 2024
```json
{
  "UserProfile": {
    "title": "Hello {firstName}"
  }
}
```

```tsx
function UserProfile({user}) {
  const t = useTranslations('UserProfile');
 
  // ✖️ Missing argument
  t('title');
 
  // ✅ Argument is provided
  t('title', {firstName: user.firstName});
}
```

**Changes**
- ICU arguments can now be validated with TypeScript (however, currently
this is
[opt-in](https://next-intl-docs-git-feat-type-safe-params-next-intl.vercel.app/docs/workflows/typescript#messages-arguments))
- `undefined` and `null` are no longer accepted as values for calls to
`t`—please only provide valid values.

Fixes #410
@amannn amannn linked a pull request Nov 7, 2024 that will close this issue
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: ergonomics enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants