next-intl icon indicating copy to clipboard operation
next-intl copied to clipboard

Type-safe arguments

Open amannn opened this issue 2 years ago • 6 comments

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:

  • https://twitter.com/trashh_dev/status/1558209179071877120/photo/1
  • https://github.com/schummar/schummar-translate/blob/master/src/extractICU.ts
  • https://github.com/QuiiBz/next-international/tree/main/packages/international-types#type-safe-params

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 https://github.com/amannn/next-intl/issues/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. https://github.com/amannn/next-intl/issues/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 avatar Jul 20 '23 10:07 amannn

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

DemianParkhomenko avatar Aug 07 '23 05:08 DemianParkhomenko

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

TommySorensen avatar Aug 18 '23 13:08 TommySorensen

any updates on this one?

matannahmani avatar Nov 29 '23 08:11 matannahmani

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 {}

loczek avatar Dec 16 '23 02:12 loczek

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}"
}

DemianParkhomenko avatar Dec 16 '23 07:12 DemianParkhomenko

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.

ScreamZ avatar May 03 '24 15:05 ScreamZ