react-i18next icon indicating copy to clipboard operation
react-i18next copied to clipboard

react-i18next <Trans /> component values are not type safe

Open samuelpucat opened this issue 7 months ago • 4 comments

🐛 Bug Report

When using react-i18next <Trans /> component, prop values provides no intellisense and throws no TS errors.

To Reproduce

I followed these tutorials:

  • https://www.i18next.com/overview/typescript
  • https://www.youtube.com/watch?v=GLIas4DH3Ww
  1. I generated /src/@types/resources.d.ts with i18next-resources-for-ts interface -i ./public/locales/en -o ./src/@types/resources.d.ts script:
// resources.d.ts

interface Resources {
  "translation": {
    ...
    "title": "Title: <strong>{{appName}}</strong>",
    ...
  },
  ...
}
export default Resources;
  1. I created /src/@types/i18next.d.ts:
// i18next.d.ts

import Resources from './resources'

declare module 'i18next' {
    interface CustomTypeOptions {
        defaultNS: 'translation';
        resources: Resources;
        allowObjectInHTMLChildren: true;
    }
}
  1. I added /public/locales/en/translation.json
{
    "title": "Title: <strong>{{appName}}</strong>"
}
  1. I used the translation like this:
<Trans
  t={t}
  i18nKey="title"
  values={{
    appName: 'Super duper app',
    // wrong value key but no TS error
    // apName: 'Super duper app',
  }}
/>

or this:

<Trans
  t={t}
  i18nKey="title"
>
  {/* wrong value key but no TS error */}
  Title <strong>{{apName: 'Super duper app'}}</strong>
</Trans>

i18nKey had good intellisense and threw TS error when I typed a different key but wrong values key didn't throw any error.

Expected behavior

I would expect same error as when using t function with wrong value keys:

{/* wrong value key with correct TS error */}
{t('title', { apName: appName })}

throws error:

Argument of type '["title", { apName: "Super duper app"; }]' is not assignable to parameter of type '[key: "title" | "title"[], options?: ({ readonly apName: "Super duper app"; } & { appName: unknown; }) | undefined] | [key: string | string[], options: { readonly apName: "Super duper app"; } & $Dictionary & { ...; }] | [key: ...]'.
  Type '["title", { apName: "Super duper app"; }]' is not assignable to type '[key: string | string[], defaultValue: string, options?: ({ readonly apName: "Super duper app"; } & $Dictionary) | undefined]'.
    Type at position 1 in source is not compatible with type at position 1 in target.
      Type '{ apName: "Super duper app"; }' is not assignable to type 'string'.

Your Environment

  • node version: v20.14.0
  • typescript version: 5.2.2
  • i18next version: 23.12.1
  • react-i18next version: 14.1.2
  • i18next-resources-for-ts version: 1.5.0

Thanks

P.S.: If this issue belongs to react-i18next package, please let me know and I'll move it there.

samuelpucat avatar Jul 16 '24 13:07 samuelpucat