vue-i18n
vue-i18n copied to clipboard
`i18n.global.locale` type definiton wrong
Reporting a bug?
When I implemented a function to globally switch locale as follows:
The type definition for i18n.global.locale
is wrong:
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
- [X] Read the Contributing Guidelines
- [X] Read the Documentation
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion
- [X] The provided reproduction is a minimal reproducible example of the bug.
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
Thank you for your reporting!
I seem that the i18n instance is created with
createI18n
withlegacy: 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#globalYou 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 ...
});
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.
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
Have the same problem with next-version. With legacy: false
i have to set it with i18n.global.locale.value = locale;
I'm facing the same problem I think, getting an unknown type from locale
which is causing errors with v-model
:


A workaround for me is using the implicit way:
<RadioGroup v-model="$i18n.locale">
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>
.
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>
:
@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>
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.