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: Type 'TFunctionResult' is not assignable to type 'ReactNode'. #1795

Closed
HT-Moh opened this issue Apr 13, 2022 · 50 comments
Closed
Assignees

Comments

@HT-Moh
Copy link

HT-Moh commented Apr 13, 2022

Describe the bug

You must provide a clear and concise description of what the bug is.

Occurs in next-i18next version

11.0.0

Steps to reproduce

update to react 18

Expected behaviour

You must provide a clear and concise description of what you expected to happen.

Screenshots

image

Additional context

This seems to be due to the following two issues
DefinitelyTyped/DefinitelyTyped#46691
DefinitelyTyped/DefinitelyTyped#56210

Solution

pumping react-i18next to the last version which contain the commit

@HT-Moh
Copy link
Author

HT-Moh commented Apr 14, 2022

The following solution worked for me:
Update packages react and react-dom and types

 "react": "^18.0.0",
 "react-dom": "^18.0.0",
 @types/react": "^18.0.4",
 @types/react-dom": "^18.0.0"

Add the following to package.json

"resolutions": {
    "react-i18next": ">=11.16.4"
  }

@HT-Moh HT-Moh closed this as completed Apr 14, 2022
@azuken
Copy link

azuken commented May 2, 2022

"resolutions": {
"react-i18next": ">=11.16.4"
}

This is a workaround fix, will an update be available soon ?

EDIT : And this is not working anyway

@quertenmont
Copy link

I am having the same issue and the working around is indeed not working
image

@qjnz
Copy link

qjnz commented May 5, 2022

I have the same issue

I am having the same issue and the working around is indeed not working image

I am having the same issue by using the latest package react-i18next v11.16.8

@MouzamSadiq
Copy link

place "as string " to it . eg {t."dashboard.title,"dashboad") as string}

@phankietit
Copy link

Fix by update rn i18next version: Here

@adriandmitroca
Copy link

Still broken in latest release (11.16.9): Type 'TFunctionResult' is not assignable to type 'ReactNode'.

@bedcoding
Copy link

bedcoding commented May 30, 2022

I also had the same error when applying TypeScript in i18n.

Type 'TFunctionResult' is not assignable to type 'ReactNode'.
  Type 'object' is not assignable to type 'ReactNode'.
    Type '{}' is missing the following properties from type 'ReactPortal': key, children, type, propsts(2322)

So I modified it as follows.

{t("base.content.no")}
=> {t<string>("base.content.no")}

스크린샷 2022-05-30 오전 11 09 18

or

{t("brand.button.management")}
=> {`${t("brand.button.management")}`}

@marcoXbresciani
Copy link

{${t("brand.button.management")}}

This one is working for me.

  • react-i18next ^11.17.1
  • i18next ^21.6.16

marcoXbresciani pushed a commit to marcoXbresciani/TKCompanionApp that referenced this issue Jun 10, 2022
@keremcanb
Copy link

keremcanb commented Jun 15, 2022

I'm getting this error if it is only used like this:

import i18n from 'i18next';

i18n.t('text.example')

No problems with this:

import { useTranslation } from 'react-i18next';

const { t } = useTranslation();

t('text.example')

@Shackey666
Copy link

Shackey666 commented Jul 8, 2022

Hello, I still have this bug on my side too.

package.json:

peerDep: {
"i18next": "^21.8.11",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^11.18.0",
}

devDependencies: {
"@types/react": "^18.0.14",
"@types/react-dom": "^18.0.5",
}

issue example: {t('cart.step.regular')} with const { t } = useTranslation();

Any other solutions than the one proposed before?

@HT-Moh
Copy link
Author

HT-Moh commented Jul 14, 2022

The other solution is to update all packages to the last version and remove the devDependencies entry, for me the following versions work

"react": "^18.2.0",
"react-dom": "^18.2.0",
 "@types/react": "^18.0.15",
 "@types/react-dom": "^18.0.6",

update all eslint and it's plugins
what works for me last versions

    "eslint": "^8.19.0",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-jsx-a11y": "^6.6.0",
    "eslint-plugin-prettier": "^4.2.1",
    "eslint-plugin-react": "^7.30.1",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-security": "^1.5.0",
    "eslint-plugin-simple-import-sort": "^7.0.0",
    "eslint-plugin-sonarjs": "^0.13.0",
    "eslint-plugin-unicorn": "^43.0.1",

to check the package that needs to be updated run yarn outdated
I hope this helps.

@sigespweb22
Copy link

Correção por atualização rn i18next version: Aqui

It worked for me. Thanks

@Dam998
Copy link

Dam998 commented Sep 20, 2022

you can do something like that too:

export type i18translateType = {
  t: (key: string | TemplateStringsArray | (string | TemplateStringsArray)[], options?: string | TOptions<StringMap> | undefined) => string
}

const component = (props: ...) => {
  const { t }: i18translateType = useTranslation();
  ...
  
  return <div>
    ...
    <p>{t("text")}</p>
    ...
    <button>{t("dashboard")}</button>
  </div>
}

@layerok
Copy link

layerok commented Sep 21, 2022

updating typescript to ^4.8.3 helped me

@MarcelGeo
Copy link

If I am using withTranslation() HOC, fix in newest version is not available. Same error:

(property) placeholder?: ReactNode
Type 'TFunctionResult' is not assignable to type 'ReactNode'

@OnkelTem
Copy link

OnkelTem commented Oct 9, 2022

I don't quite understand what this mess is all about. Could the author provide an explanation?

Here is a mini-demo of the problem: TypeScript Sandbox

import { TFunction as TFunctionNext } from 'next-i18next'
import { TFunction as TFunctionReact } from 'react-i18next'

type Foo = {
  title: React.ReactNode
}

function barNext(foo: Foo, t: TFunctionNext) {
    foo.title = t('Prodict title') 
//  ^^^^^^^^^
//  ERROR:
//   Type 'TFunctionResult' is not assignable to type 'ReactNode'.
//      Type 'object' is not assignable to type 'ReactNode'.(2322)
}

function barReact(foo: Foo, t: TFunctionReact) {
    foo.title = t('Prodict title')
}

Conclusions (for TS 4.7.4 & 4.8.4 that I both tried):

  1. TFunction from react-i18next doesn't produce any problems.
  2. TFunction from next-i18next is the culprit.

Can it be just fixed?

Meanwhile, in such circumstances I would just change all TFunction imports to react-i18next

@OnkelTem
Copy link

OnkelTem commented Oct 9, 2022

@HT-Moh I see this one is closed. Well, should I file a new report?

ivan-aksamentov added a commit to nextstrain/nextclade that referenced this issue Oct 21, 2022
I downgraded i18n packages in previous commit (3604038), but these versions have defects in Typescipt typings:
i18next/next-i18next#1795

Instead of the default hook, let's use a wrapper with enforced correct types everywhere.
@ivansvlv
Copy link

I was just migrating the app to React 18 and latest TypeScript and faced the same issue.

"dependencies" : {
    "i18next": "^22.0.1",
    "i18next-browser-languagedetector": "^6.1.8",
    "i18next-http-backend": "^1.4.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-i18next": "^12.0.0",
},
"devDependencies": {
    "@types/react": "^18.0.21",
    "@types/react-dom": "^18.0.6",
    "@typescript-eslint/eslint-plugin": "^5.40.1",
    "@typescript-eslint/parser": "^5.40.1",
    "eslint": "^8.25.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-jsx-a11y": "^6.6.1",
    "eslint-plugin-react": "^7.31.10",
    "eslint-plugin-react-hooks": "^4.6.0",
    "typescript": "^4.8.4",
}
const { t } = useTranslation('footer');

            <div>
              <Link to="/terms-conditions">{t('links.terms-conditions')}</Link>
              <Link to="/privacy-policy">{t('links.privacy-policy')}</Link>
            </div>

This t() usage type error:

Type 'DefaultTFuncReturn' is not assignable to type 'ReactI18NextChild | Iterable<ReactI18NextChild>'.ts(2322) index.d.ts(47, 5): The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & LinkProps & RefAttributes<HTMLAnchorElement>'

However, I can see relevant type definitions that should allow this. Similar error is noticed with general JSX tags:

  const { t } = useTranslation(['login', 'errors']);

        <LoginHeader>
          <h1 className={style.login__title}>{t('login:signin.title')}</h1>
          <p className={style.login__paragraph}>{t('login:signin.subtitle')}</p>
        </LoginHeader>

Type 'DefaultTFuncReturn' is not assignable to type 'ReactI18NextChild | Iterable<ReactI18NextChild>'.ts(2322) index.d.ts(47, 5): The expected type comes from property 'children' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>'

I've already tried to remove package-lock.json and node_modules to have a clean install, but it didn't help.

@fitimbytyqi
Copy link

fitimbytyqi commented Oct 21, 2022

I was just migrating the app to React 18 and latest TypeScript and faced the same issue.

"dependencies" : {
    "i18next": "^22.0.1",
    "i18next-browser-languagedetector": "^6.1.8",
    "i18next-http-backend": "^1.4.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-i18next": "^12.0.0",
},
"devDependencies": {
    "@types/react": "^18.0.21",
    "@types/react-dom": "^18.0.6",
    "@typescript-eslint/eslint-plugin": "^5.40.1",
    "@typescript-eslint/parser": "^5.40.1",
    "eslint": "^8.25.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-jsx-a11y": "^6.6.1",
    "eslint-plugin-react": "^7.31.10",
    "eslint-plugin-react-hooks": "^4.6.0",
    "typescript": "^4.8.4",
}
const { t } = useTranslation('footer');

            <div>
              <Link to="/terms-conditions">{t('links.terms-conditions')}</Link>
              <Link to="/privacy-policy">{t('links.privacy-policy')}</Link>
            </div>

This t() usage type error:

Type 'DefaultTFuncReturn' is not assignable to type 'ReactI18NextChild | Iterable<ReactI18NextChild>'.ts(2322) index.d.ts(47, 5): The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & LinkProps & RefAttributes<HTMLAnchorElement>'

However, I can see relevant type definitions that should allow this. Similar error is noticed with general JSX tags:

  const { t } = useTranslation(['login', 'errors']);

        <LoginHeader>
          <h1 className={style.login__title}>{t('login:signin.title')}</h1>
          <p className={style.login__paragraph}>{t('login:signin.subtitle')}</p>
        </LoginHeader>

Type 'DefaultTFuncReturn' is not assignable to type 'ReactI18NextChild | Iterable<ReactI18NextChild>'.ts(2322) index.d.ts(47, 5): The expected type comes from property 'children' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>'

I've already tried to remove package-lock.json and node_modules to have a clean install, but it didn't help.

I'm running into the same issue with the versions mentioned above, have you found any solutions yet ?

Oh, I found a solutions for it, just downgrade react-i18next to version 11.18.6 and it'll solve the issue. Seems like the issue is with version 12

@ivansvlv
Copy link

@fitimbyttyqi thanks, that helped indeed. Version ^11.18.6 works fine.

@cjsilva-umich
Copy link

Would be great if this could be looked into so that version 12 could be used without this error

@imransilvake
Copy link

imransilvake commented Oct 25, 2022

working with ^11.18.6
problem with ^12.0.0

@ben-lawlor-k
Copy link

I also had the same error when applying TypeScript in i18n.

Type 'TFunctionResult' is not assignable to type 'ReactNode'.
  Type 'object' is not assignable to type 'ReactNode'.
    Type '{}' is missing the following properties from type 'ReactPortal': key, children, type, propsts(2322)

So I modified it as follows.

{t("base.content.no")}
=> {t<string>("base.content.no")}

스크린샷 2022-05-30 오전 11 09 18

or

{t("brand.button.management")}
=> {`${t("brand.button.management")}`}

This works with react-i18next ^12.0.0

@Tautorn
Copy link

Tautorn commented Oct 26, 2022

working with ^11.18.6 problem with ^12.0.0

It works for me. Thank you.

I did update to version 12.0.0 and it generated the error. Was it necessary a downgrade version.

@imransilvake
Copy link

working with ^11.18.6 problem with ^12.0.0

It works for me. Thank you.

I did update to version 12.0.0 and it generated the error. Was it necessary a downgrade version.

Yes until there is a standard fix from the team.

@pedrodurek
Copy link
Member

This PR will fix that, there is only one small downside that I'll describe there.

@adrai
Copy link
Member

adrai commented Oct 27, 2022

can you try with i18next v22.0.3?

@ben-lawlor-k
Copy link

can you try with i18next v22.0.3?

Working with i18next v22.0.3 and react-i18next v12.0.0. Thank you!

@adrai adrai closed this as completed Oct 27, 2022
@gHashTag
Copy link

the following versions work for me

"i18next": "22.0.4",
"react-i18next": "12.0.0",

@nick4fake
Copy link

@gHashTag I have same versions, it doesn't work

@adrai
Copy link
Member

adrai commented Nov 13, 2022

and with i18next v22.0.5?

@nick4fake
Copy link

@adrai Exactly the same error after updating to 22.0.5

@nick4fake
Copy link

@adrai I am really sorry, apparently I've had it cached. 22.0.5 works! Thanks

@EnvyIT
Copy link

EnvyIT commented Nov 29, 2022

@adrai this issues should be re-open. it still is a problem with:

"i18next": "^22.0.6",
"react": "18.2.0",
"react-i18next": "^12.0.0",


"typescript": "^4.9.3",

Leads to TS error : TS2322: Type 'DefaultTFuncReturn' is not assignable to type 'string | undefined'.   Type 'null' is not assignable to type 'string | undefined'.

When can you provide a fix that is working as expected?

@adrai
Copy link
Member

adrai commented Nov 29, 2022

@adrai this issues should be re-opned. it still is a problem with:

"i18next": "^22.0.6",
"react": "18.2.0",
"react-i18next": "^12.0.0",


"typescript": "^4.9.3",

Leads to TS error : TS2322: Type 'DefaultTFuncReturn' is not assignable to type 'string | undefined'.   Type 'null' is not assignable to type 'string | undefined'.

When can you provide a fix that is working as expeced?

@EnvyIT you have a different issue: https://www.i18next.com/overview/typescript#argument-of-type-defaulttfuncreturn-is-not-assignable-to-parameter-of-type-xyz

@EnvyIT
Copy link

EnvyIT commented Nov 29, 2022

Well , you are right @adrai thanks for your fast response. Was this introduced in a specific version? I am curious because in 21.8.10 it is working perfectly fine.

@adrai
Copy link
Member

adrai commented Nov 29, 2022

Well , you are right @adrai thanks for your fast response. Was this introduced in a specific version? I am curious because in 21.8.10 it is working perfectly fine.

Yes, in the last major v22

@kirillleogky
Copy link

"next": "^12.3.0",
"next-i18next": "^13.0.0",
"react": "17.0.2",
"react-i18next": "^12.0.0",
"i18next": "^22.0.6",

my next-i18next.config.js:

module.exports = {
  i18n: {
    locales: ['en'],
    defaultLocale: 'en',
  },
};

inside app:


import { useTranslation } from 'react-i18next';
....
const [label, setLabel] = useState('');
const { t } = useTranslation();
...
setLabel(t('common:continue'));

image

I don't get where I need to put returnNull: false,

@adrai
Copy link
Member

adrai commented Nov 29, 2022


"next": "^12.3.0",

"next-i18next": "^13.0.0",

"react": "17.0.2",

"react-i18next": "^12.0.0",

"i18next": "^22.0.6",

my next-i18next.config.js:


module.exports = {

  i18n: {

    locales: ['en'],

    defaultLocale: 'en',

  },

};

inside app:




import { useTranslation } from 'react-i18next';

....

const [label, setLabel] = useState('');

const { t } = useTranslation();

...

setLabel(t('common:continue'));



image

I don't get where I need to put returnNull: false,

module.exports = {
  i18n: {
    locales: ['en'],
    defaultLocale: 'en',
  },
  returnNull: false,
};

@kirillleogky
Copy link


"next": "^12.3.0",

"next-i18next": "^13.0.0",

"react": "17.0.2",

"react-i18next": "^12.0.0",

"i18next": "^22.0.6",

my next-i18next.config.js:


module.exports = {

  i18n: {

    locales: ['en'],

    defaultLocale: 'en',

  },

};

inside app:




import { useTranslation } from 'react-i18next';

....

const [label, setLabel] = useState('');

const { t } = useTranslation();

...

setLabel(t('common:continue'));

image
I don't get where I need to put returnNull: false,

module.exports = {
  i18n: {
    locales: ['en'],
    defaultLocale: 'en',
  },
  returnNull: false,
};

still the same
i even re-install modules but nothing

image

maybe smth wrong inside next.config.js

/** @type {import('next').NextConfig} */
const { i18n } = require('./next-i18next.config');
const withPWA = require('next-pwa');

const nextConfig = {
  i18n,
  // Due to Material UI styles mismatch
  reactStrictMode: false,
  fallback: true,
  images: {
    loader: 'custom',
  },

  compiler: {
    emotion: true,
  },

  pwa: {
    dest: 'public',
    swSrc: 'service-worker.js',
    disable: process.env.NODE_ENV === 'development',
    // cacheOnFrontEndNav: true,
    fallbacks: {
      image: '/assets/default-image.png',
    },
  },

  publicRuntimeConfig: {
......
  },

  serverRuntimeConfig: {
....
  },

  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      use: ['@svgr/webpack'],
    });

    return config;
  },

  async redirects() {
    return [
      {
        source: '/admin',
        destination: '/admin/performance',
        permanent: true,
      },
      {
        source: '/creator',
        destination: '/creator/episodes',
        permanent: true,
      },
    ];
  },
};

module.exports = withPWA(nextConfig);

@adrai
Copy link
Member

adrai commented Nov 29, 2022

@kirillleogky did you also set returnNull in the i18next.d.ts file?

// i18next.d.ts
import 'i18next';

declare module 'i18next' {
  interface CustomTypeOptions {
    returnNull: false;
    ...
  }
}

If so, please create a minimal reproducible example and open a new issue.

@zhrivodkin
Copy link

import { useTranslation } from 'next-i18next';
const { t } = useTranslation(['layout']);
...
<Button size="xs" kind="secondary">
  {t('signup_submit')}
</Button>

package.json:

"i18next": "^22.4.9",
"next": "^13.1.5",
"next-i18next": "^13.1.4",
"react-i18next": "^12.1.5"

Still not working.

@adrai
Copy link
Member

adrai commented Feb 9, 2023

@zhrivodkin did you try: https://www.i18next.com/overview/typescript#argument-of-type-defaulttfuncreturn-is-not-assignable-to-parameter-of-type-xyz ?

@zhrivodkin
Copy link

@zhrivodkin did you try: https://www.i18next.com/overview/typescript#argument-of-type-defaulttfuncreturn-is-not-assignable-to-parameter-of-type-xyz ?

Oh, thank you so much! Among the waterfall of comments I did not see the solution.

@mleister97
Copy link

Still didn't get it running. The solution did not work. Any updates?

@FranciscoOssian
Copy link

It may not necessarily be a bug, but somehow it ends up causing a problem. Ideally, the function should return a string with a fallback value.

const { t: translation, i18n } = useTranslation();
const t = (s: string) => translation<string>(s);

I went with this approach so I don't have to make changes throughout the entire file. By the way, I'm migrating the code to ts, and this issue hasn't come up before.

@IberaSoft
Copy link

A potential solution could be:

<div>{t<string>('your-label')}</div>

or

<div>{${t('your-label')}}</div>

@voliva
Copy link

voliva commented May 22, 2023

I've used the following patch, and it seems to be working fine:

diff --git a/node_modules/i18next/index.d.ts b/node_modules/i18next/index.d.ts
index e7b769d..045e4e1 100644
--- a/node_modules/i18next/index.d.ts
+++ b/node_modules/i18next/index.d.ts
@@ -690,6 +690,13 @@ export type TFunctionResult =
 export type TFunctionKeys = string | TemplateStringsArray;
 export interface TFunction {
   // basic usage
+  <
+    TKeys extends TFunctionKeys = string,
+    TInterpolationMap extends object = StringMap,
+  >(
+    key: TKeys | TKeys[],
+    options?: TOptions<TInterpolationMap> | string,
+  ): string;
   <
     TResult extends TFunctionResult = string,
     TKeys extends TFunctionKeys = string,

I've just added an overload that returns a simple string, which is what's mostly expected when using the TFunction.

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