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 error with i18next@23.7.2+ #1693

Closed
rktyt opened this issue Nov 13, 2023 · 26 comments
Closed

Type error with i18next@23.7.2+ #1693

rktyt opened this issue Nov 13, 2023 · 26 comments

Comments

@rktyt
Copy link

rktyt commented Nov 13, 2023

🐛 Bug Report

The following error occurs:

error TS2741: Property 'reportNamespaces' is missing in type 'import("/tmp/test/node_modules/i18next/index").i18n' but required in type 'import("/tmp/test/node_modules/i18next/index").i18n'.

More details:
スクリーンショット 2023-11-13 18 54 36


No errors with i18next versions 27.6.0, 27.7.0, 27.7.1.
I’m got errors with i18next versions 27.7.2, 27.7.3.

To Reproduce

The following three files are required to reproduce.

index.tsx:

import { createInstance } from 'i18next'
import type { ReactNode } from 'react'
import { initReactI18next, I18nextProvider } from 'react-i18next'

const i18n = createInstance()
await i18n.use(initReactI18next).init({
  lng: 'en',
  fallbackLng: 'en',
  ns: ['common'],
  defaultNS: 'common',
  debug: false,
  interpolation: {
    escapeValue: false,
  },
  resources: { en: { common: {} } },
})

export function I18nextTestStubProvider({ children }: { children: ReactNode }) {
  return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>
}

package.json:

{
  "dependencies": {
    "i18next": "23.7.3",
    "react": "^18.2.0",
    "react-i18next": "^13.4.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.37",
    "typescript": "^5.2.2"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "strictNullChecks": true,
    "removeComments": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "baseUrl": "."
  }
}

After creation, check with npm install && npx tsc --noEmit

Expected behavior

No type errors.

Your Environment

  • runtime version: node v18
  • i18next version: 23.7.3
  • os: Linux

Additionnal context

Probably the same as #1379.
However, the cause seems to be different because multiple versions of i18next are not installed.

@adrai
Copy link
Member

adrai commented Nov 13, 2023

Can you provide a reproducible example please?

@rktyt
Copy link
Author

rktyt commented Nov 13, 2023

@adrai
I've updated it to include everything you need to reproduce it.

@konomae
Copy link

konomae commented Nov 13, 2023

Same here 🙋‍♂️

I also created a minimum reproduction:
https://stackblitz.com/edit/vitejs-vite-vpz18f?file=src%2Fmain.ts

Screenshot

@adrai
Copy link
Member

adrai commented Nov 13, 2023

seems this is because of the moduleResolution set to bundler... if you change it to NodeNext, it works

@adrai
Copy link
Member

adrai commented Nov 13, 2023

i18next/i18next#2063

@stevensacks
Copy link

stevensacks commented Nov 13, 2023

@adrai remix-utils requires "moduleResolution": "Bundler" in tsconfig to resolve ESM/CJS conflicts.

@adrai
Copy link
Member

adrai commented Nov 13, 2023

If you have an idea on how to "fix" this, feel free to provide a PR.

@adrai
Copy link
Member

adrai commented Nov 13, 2023

@stevensacks
Copy link

cc: @sergiodxa (the author of remix-i18next)

@adrai
Copy link
Member

adrai commented Nov 13, 2023

v13.4.1 should be better

@adrai
Copy link
Member

adrai commented Nov 13, 2023

i18next v23.7.6 + react-i18next v13.4.1

@adrai
Copy link
Member

adrai commented Nov 13, 2023

Alternatively, try to cast it:

import { createInstance, i18n as I18N } from "i18next";
import { useTranslation } from "react-i18next";

const i18n = createInstance();
useTranslation("test", { i18n: i18n as I18N });

@stevensacks
Copy link

stevensacks commented Nov 14, 2023

Still a type issue in 23.7.6 and 13.4.1 when setting the <I18NextProvider i18n={instance}/>

Is there something I can add to the react-i18next.d.ts file?

This is what I have now.

import type resources from '~/languages/en';
import 'react-i18next';

declare module 'i18next' {
    interface CustomTypeOptions {
        resources: typeof resources;
    }
}

Everything still works as expected when I @ts-ignore the type error.

// @ts-ignore
<I18nextProvider i18n={instance}>

@adrai
Copy link
Member

adrai commented Nov 14, 2023

Did you try to cast it? Like here: #1693 (comment)

@stevensacks
Copy link

Yes, but it doesn’t resolve the type error with the Provider i18n prop. The example above is used with the useTranslation hook, but that isn’t an issue in remix. Just the provider.

@adrai
Copy link
Member

adrai commented Nov 14, 2023

Did you try this?

import { i18n as I18N } from "i18next";
// ...
<I18nextProvider i18n={instance as I18N}>

@adrai
Copy link
Member

adrai commented Nov 14, 2023

This works for me:

import { createInstance, i18n as I18N } from 'i18next'
import type { ReactNode } from 'react'
import { initReactI18next, I18nextProvider } from 'react-i18next'

const i18n = createInstance()
i18n.use(initReactI18next).init({
  lng: 'en',
  fallbackLng: 'en',
  ns: ['common'],
  defaultNS: 'common',
  debug: false,
  interpolation: {
    escapeValue: false,
  },
  resources: { en: { common: {} } },
})

export function I18nextTestStubProvider({ children }: { children: ReactNode }) {
  return <I18nextProvider i18n={i18n as I18N}>{children}</I18nextProvider>
}

@stevensacks
Copy link

stevensacks commented Nov 14, 2023

In remix-i18next, on the entry.server file, you do this:

https://github.com/sergiodxa/remix-i18next#server-side-configuration

let instance = createInstance();
  let lng = await i18next.getLocale(request);
  let ns = i18next.getRouteNamespaces(remixContext);

  await instance
    .use(initReactI18next) // Tell our instance to use react-i18next
    .use(Backend) // Setup our backend
    .init({
      ...i18n, // spread the configuration
      lng, // The locale we detected above
      ns, // The namespaces the routes about to render wants to use
      backend: { loadPath: resolve("./public/locales/{{lng}}/{{ns}}.json") },
    });

  return new Promise((resolve, reject) => {
    let didError = false;

    let { pipe, abort } = renderToPipeableStream(
      <I18nextProvider i18n={instance}>
        <RemixServer context={remixContext} url={request.url} />
      </I18nextProvider>,

I tried i18n={instance as I18N} but the error persists.

@adrai
Copy link
Member

adrai commented Nov 14, 2023

You're still not casting the instance in your code.

Instead of:

<I18nextProvider i18n={instance}> <RemixServer context={remixContext} url={request.url} /> </I18nextProvider>,

Do:

<I18nextProvider i18n={instance as I18N}> <RemixServer context={remixContext} url={request.url} /> </I18nextProvider>,

@stevensacks
Copy link

stevensacks commented Nov 14, 2023

That’s not my code, I pasted the code example from the docs I linked to. Sorry for the confusion I was trying to add more context.

In my code, I cast it as I mentioned:

I tried i18n={instance as I18N} but the error persists.

@adrai
Copy link
Member

adrai commented Nov 14, 2023

So can you please provide your complete reproducible Code repository?
Or keep the ts-ignore 🤷‍♂️

@stevensacks
Copy link

Can’t do the first, unfortunately. I’ll keep the ts-ignore but other remix-i18next users may run into the same issue so I’ll have Sergio make a note about it.

@stevensacks
Copy link

Got it working with the casting.

fernandocanizo added a commit to fernandocanizo/learning-remix-with-i18n that referenced this issue Nov 22, 2023
According to i18next/react-i18next#1693
you can fix the Typescript error on `reportNamespaces` by changing
`module` and `moduleResolution` on TS config.

This raises new TS errors, but let's see where the path leaves us.
fernandocanizo added a commit to fernandocanizo/learning-remix-with-i18n that referenced this issue Nov 22, 2023
Applied @adrai suggested solution from
i18next/react-i18next#1693

but still got TS errors :'(

So I guess the solution for the time being would be to just ts-ignore
the problematic lines.
@tgds
Copy link

tgds commented Dec 21, 2023

this module augmentation is the problem:

reportNamespaces: ReportNamespaces;

the property should be optional. however, changing it to optional might be a breaking change?

@adrai adrai closed this as completed in 7e88547 Dec 21, 2023
@adrai
Copy link
Member

adrai commented Dec 21, 2023

v14.0.0 has just been released that should make it optional

@tgds
Copy link

tgds commented Dec 21, 2023

v14.0.0 has just been released that should make it optional

thanks for the super quick release!

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

No branches or pull requests

5 participants