reactjstypescripti18next

i18n useTranslation 'expected 0 arguments but got 1' when adding namespace


I have recently had an issue incorporating namespaces to my i18n setup while switching from a one-file-per-language model to a more complex structured file model that requires the use of namespaces to function.

I could get the namespace loaded like this:

{t('welcome', { ns: 'auth' })}

But I figured this would be quite slow with having to write out the namespace on a page that uses it frequently. After looking up the documentation, I have found a way to declare namespaces directly inside useTranslation() function, by adding the namespace as an argument like so useTranslation('auth').

This is what my index.ts file ended up looking like:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import I18NextHttpBackend from 'i18next-http-backend';

i18n
  .use(LanguageDetector) // Automatically detects browser langauge
  .use(initReactI18next)
  .use(I18NextHttpBackend)
  .init({
    fallbackLng: 'en',
    supportedLngs: ['en', 'pl', 'de', 'ru'], // Supported languages configuration
    ns: ['general', 'countries', 'intro', 'auth'], // Namespace configuration
    interpolation: {
      escapeValue: false 
    },
    backend: {
      loadPath: 'locales/{{lng}}/{{ns}}.json' // Loading paths for different namespaces
    },
    detection: { // Order configuration for automatic language detection
      order: ['localStorage', 'cookie', 'navigator'],
      caches: ['localStorage', 'cookie']
    }
  });

export default i18n;

When I tried substituting a namespace into useTranslation() arguments, however, I have received the following error:

TS2554: Expected 0 arguments, but got 1.
    16 |
    17 | const LoginPage: React.FC = () => {
  > 18 |     const { t } = useTranslation('auth');

I am not sure why this happens, because according to the documentation it should work in this way exactly. It doesn't elaborate however, on how index.js is meant to be configured in order to use this feature.

My i18next version is 25.2.1 and my i18next-react version is 15.5.2. The TypeScript version I am using is 4.9.5 with 5.8.3 marked as deduped in other instances.

I am not quite sure wherein the root of this issue lies, however, I have tried adding an interface to useTranslation() using i18n.d.ts in my /src folder like this:

import 'react-i18next';

declare module 'react-i18next' {
  interface Resources {
    [namespace: string]: Record<string, any>;
  }
}

This did not change anything.

I would appreciate your help on this matter. Thank you!


Solution

  • The person in the comments answered it correctly to my surprise.

    i18next warns about incompatibility with versions of TypeScript below 5.0.0, and as my version in frontend was 4.9.5, it would not let me use this feature with namespaces.

    The problem is that LanguageDetector and I18NextHttpBackend only fully work with TypeScript >5.0.0, and their usage with older versions will result in surprising errors in some cases.

    TLDR: Upgrade TypeScript to >5.0.0