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

ESLint error: Unsafe assignment of an any value #2032

Open
jbanulso opened this issue Sep 8, 2023 · 10 comments
Open

ESLint error: Unsafe assignment of an any value #2032

jbanulso opened this issue Sep 8, 2023 · 10 comments
Assignees

Comments

@jbanulso
Copy link

jbanulso commented Sep 8, 2023

💥 Regression Report

Related to #2011.

Since v22.5.0, ESLint started to complain about using an any value as the returned result from the t() function. Please note that for some reason this does not happen everywhere the t function is used, just in some specific instances (haven't managed to find a pattern or the culprit though).

Previously I've worked around this issue by doing t<string>('MY.TRANSLATION.KEY'), but after the upgrade to v23.5.0 I see that is not allowed anymore, getting the same TS error message ("Expected 3-4 type arguments, but got 1") as in issue #2029

In case it makes a difference, I'm fetching the translations at runtime using i18n-http-backend, so it's not possible for me to hardcode the translations and types during build time.

Last working version

Worked up to version: with my t<string> workaround, 22.5.0 - without any workarounds this started happening in v21 I believe.

Stopped working in version: 23.0.0

To Reproduce

I've tried to recreate a somewhat minimal repro here: https://codesandbox.io/s/pensive-feather-lwwpwz?file=/src/App.tsx:222-270. Unfortunately I haven't managed ESLint to bring the said error forward, but the question remains, why does the result from the t function have any type instead of string?

Expected behavior

At least being able to use the t<string> workaround. Ideally, that the return type from the t function is consistently string, instead of varying between string and any

Your Environment

  • runtime version: node v16
  • i18next version: 23.5.0
  • os: Mac
  • react-i18next 13.2.2, i18next-http-backend 2.2.2, eslint 8.48.0
adrai added a commit that referenced this issue Sep 8, 2023
@adrai
Copy link
Member

adrai commented Sep 8, 2023

I suspect, this is because @marcalexiei forgot to change also the types for typescript v4 with #2018
v23.5.1 maybe fixes this

@adrai
Copy link
Member

adrai commented Sep 8, 2023

beside that, I have no idea, why sometimes it's any and sometimes string

@jbanulso
Copy link
Author

jbanulso commented Sep 8, 2023

@adrai sorry for the confusion, I'm using Typescript v5 in my codebase but I see now I had v4 in the codesandbox, I have corrected that.

@stale
Copy link

stale bot commented Sep 17, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Sep 17, 2023
@adrai adrai removed the stale label Sep 17, 2023
@Arman92
Copy link

Arman92 commented Sep 18, 2023

Having the same issue, using i18next 23.5.1

Update: Using Typescript v5 fixes the issue

@esetnik
Copy link

esetnik commented Sep 19, 2023

I'm having the same issue on typescript v5 but only when using keys from the default namespace. For example, in the below code the required validator and the minLength validator both exhibit the error (default namespace) however the isNumber validator does not.

// validations.ts
import i18n from '../i18n';

export const required: Validator = (value) =>
  value === null ||
  value === undefined ||
  (typeof value === 'number' && isNaN(value)) ||
  (typeof value === 'string' && value.trim().length === 0) ||
  (Array.isArray(value) && value.length === 0)
    ? i18n.t('validations.required')
    : undefined;

export const minLength: (min: number) => Validator =
  (min) => (value: string) =>
    value && value.length < min
      ? i18n.t('validations.minLength', { min })
      : undefined;

export const isNumber: Validator = (value) =>
  value && isNaN(Number(value))
    ? `${i18n.t('error:validations.number')}`
    : undefined;
image

Refactoring to declaring a variable errorMessage is able to resolve the issue.

e) => {
  const errorMessage = i18n.t('validations.required');
  return value === null ||
    value === undefined ||
    (typeof value === 'number' && isNaN(value)) ||
    (typeof value === 'string' && value.trim().length === 0) ||
    (Array.isArray(value) && value.length === 0)
    ? errorMessage
    : undefined;
};

export const minLength: (min: number) => Validator =
  (min) => (value: string) => {
    const errorMessage = i18n.t('validations.minLength', { min });
    return value && value.length < min ? errorMessage : undefined;
  };

@pedrodurek
Copy link
Member

@jbanulso, are you still facing the reported issue?

@jbanulso
Copy link
Author

@jbanulso, are you still facing the reported issue?

@pedrodurek unfortunately yes

@maksimla
Copy link

maksimla commented Dec 7, 2023

the same error
open this branch example
put code

 const keyFunction = (): string => 'part1';
    const key = keyFunction();
    console.log(key);
    console.log('with key:', i18next.t<any>(`description.${key}` )); // error
    console.log('no key', i18next.t('description.part1'));

error must 3 declarete

@recallwei
Copy link

Maybe face the same question.

Some of my i18n resources are static and stored in the front-end project, and the others are stored in the backend, and I will store the key at the same time.

For me, in my code:

const { t } = useTranslation()
t(key)

If I use the key, a variable from backend api, it cannot satisfy the type definition in the front-end project.
I cannot find a better way to solve these dynamic i18n keys except using any.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants