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

i18n.global.locale type definiton wrong #1003

Open
5 tasks done
WangHansen opened this issue May 8, 2022 · 15 comments
Open
5 tasks done

i18n.global.locale type definiton wrong #1003

WangHansen opened this issue May 8, 2022 · 15 comments
Labels
❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf typescript

Comments

@WangHansen
Copy link

Reporting a bug?

When I implemented a function to globally switch locale as follows:
截屏2022-05-07 下午11 31 39

The type definition for i18n.global.locale is wrong:
截屏2022-05-07 下午11 32 31

By printing out the console, I was able to see that i18n.global.locale should be a computed value

Expected behavior

TypeScript not throw error

Reproduction

Type definition problem

System Info

System:
  OS: macOS 12.3.1
  CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
  Memory: 171.65 MB / 16.00 GB
  Shell: 5.8 - /bin/zsh
Binaries:
  Node: 16.13.2 - ~/.nvm/versions/node/v16.13.2/bin/node
  Yarn: 1.22.10 - /usr/local/bin/yarn
  npm: 8.6.0 - ~/.nvm/versions/node/v16.13.2/bin/npm
  Watchman: 2021.10.18.00 - /usr/local/bin/watchman
Browsers:
  Brave Browser: 91.1.26.77
  Chrome: 101.0.4951.54
  Safari: 15.4

"vue": "^3.2.25",
"vue-i18n": "^9.1.10",
"@intlify/vite-plugin-vue-i18n": "^3.4.0",
"@vitejs/plugin-vue": "^2.3.1",

Screenshot

No response

Additional context

No response

Validations

@WangHansen WangHansen added the Status: Review Needed Request for review comments label May 8, 2022
@kazupon
Copy link
Member

kazupon commented May 9, 2022

Thank you for your reporting!

I seem that the i18n instance is created with createI18n with legacy: true option.

The global property can refer to Composer or VueI18n, as described in the API docs.
https://vue-i18n.intlify.dev/api/general.html#global

You can check the mode of an i18n instance with mode.
https://vue-i18n.intlify.dev/api/general.html#mode

@kazupon kazupon removed the Status: Review Needed Request for review comments label May 9, 2022
@WangHansen
Copy link
Author

Thank you for your reporting!

I seem that the i18n instance is created with createI18n with legacy: true option.

The global property can refer to Composer or VueI18n, as described in the API docs. https://vue-i18n.intlify.dev/api/general.html#global

You can check the mode of an i18n instance with mode. https://vue-i18n.intlify.dev/api/general.html#mode

Sorry, should specify, I actually created with legacy: false:

const i18n = createI18n<I18nOptions, [MessageSchema], 'zh-CN' | 'en-CA'>({
  legacy: false,
  locale: getLang(),
  messages: {
    'zh-CN': zhCN,
    'en-CA': enCA,
  },
  // something vue-i18n options here ...
});

@markbrockhoff
Copy link

Hi, I was facing the same problem on vue-i18n 9.2.0-beta.31.

I had a look at the type of i18n.global.locale and it's of type string | WritableComputedRef. So you can't access .value unless you tell Typescript that i18n.global.locale is not a string but a ref.
Therefore I just added a typeguard using the isRef function from vue:

export const changeLocale = (i18n: I18n, locale: string) => {
  if (i18n.mode === 'legacy') {
    i18n.global.locale = locale;
  } else if (isRef(i18n.global.locale)) {
    i18n.global.locale.value = locale;
  }
};

That way the type changes to Ref inside the else block.
But this behaviour should be documented as the example in the Documentation does currently not work for Typescript.

@leo-martin
Copy link

leo-martin commented Jul 6, 2022

Hi I am facing the same issue.

I'm using i18n 9.1.10 (fixed version)

Here is my i18n setup

const i18n = createI18n({
  locale: 'fr',
  legacy: false,
  fallbackLocale: 'en',
  globalInjection: true,
  messages: messages as LocaleMessages<VueMessageType>,
})

In the same file, I try to access and modify the locale using i18n.global.locale. When I check in my code, the type for i18n.global.locale is a ref but if I try i18n.global.locale.value = 'fr' then I get a console error saying i18n.global.locale is a String and if I log i18n.global.locale.value I get undefined

I've checked and I'm using the composition mode (i18n.mode is composition) . I've tried checking with isRef, and it always returns false even though mode is composition.

Any help is appreciated

@porkus1990
Copy link

Have the same problem with next-version. With legacy: false i have to set it with i18n.global.locale.value = locale;

@valgeirb
Copy link

valgeirb commented Aug 5, 2022

I'm facing the same problem I think, getting an unknown type from locale which is causing errors with v-model:

Screenshot 2022-08-05 at 10 21 41

Screenshot 2022-08-05 at 10 23 01

A workaround for me is using the implicit way:

<RadioGroup v-model="$i18n.locale">

@timothymctim
Copy link

To me it’s clear that this bug only occurs when useScope: 'global' in useI18n is specified.
That is, with const { locale } = useI18n() I get const locale: WritableComputedRef<string>, while with const { locale } = useI18n({ useScope: 'global' }); I get const locale: WritableComputedRef<unknown>.

@it-xtech-dev
Copy link

I'm using [email protected] and having issues with global.locale type. Type recognition says its a string while with legacy: false should be ref<string>:
Zrzut ekranu 2022-08-30 o 19 26 23

@rfox12
Copy link

rfox12 commented Sep 3, 2022

@kazupon I believe @timothymctim has laid out the scenario quite well. Non-legacy users are having trouble getting Locale to type correctly to WritableComputedRef<Locale>

@kazupon kazupon added the Status: In Progress Work in Progress label Sep 3, 2022
@kazupon
Copy link
Member

kazupon commented Sep 3, 2022

sorry, I'm focusing on nuxtjs/i18n for v8 alpha release. please

Type definitions in vue-i18n are really complex.
I’m not a full-time OSS yet, so it may take some time until I'm starting on this issue.

@kazupon kazupon added ❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf typescript and removed Status: In Progress Work in Progress labels Nov 15, 2022 — with Volta.net
@mberrg
Copy link

mberrg commented Mar 23, 2023

I'm experiencing the same problem in 9.2.2

Any update on this?

@timothymctim
Copy link

I’m currently working around this issue by exporting the result of createI18n in a separate file and importing this in main.ts (where you create the app and call app.use(i18n);) and wherever I need access to the global i18n object. For example,

import i18n from 'path/to/file/calling/createI18n.ts';

function myFunctionNeedingTheGlobalI18nObject() {
  const { locale } = i18n.global;  // or anything else you need
  // rest of code
}

Here, locale now types as const locale: WritableComputedRef<string>.

@benlind
Copy link

benlind commented May 30, 2023

I was also encountering this issue:

Argument of type 'string' is not assignable to parameter of type 'Ref'.

Passing legacy: false to createI18n fixed it for me.

@Narkoleptika
Copy link

I also ran into this issue while trying to define types using createI18n<>. I was already passing legacy: false and that was working ok, but as soon as I added the type definition in the brackets <>, it started throwing type errors. Turns out you also need to pass the legacy option as part of the type definition.

Using the example from the docs

const i18n = createI18n<[MessageSchema], 'en-US' | 'ja-JP', false>({
  legacy: false,
  locale: 'en-US',
  messages: {
    'en-US': enUS
  }
})

Notice the false after 'en-US' | 'ja-JP'

Adding that fixed the issue for me.

@ibrahimBeladi
Copy link

ibrahimBeladi commented May 29, 2024

Even with passing that legacy is false in the types parameters/arguments, the Locale is still string in the template
I am on v9.13.1

Update: still occurs in v10

image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf typescript
Projects
None yet
Development

No branches or pull requests