[typescript] I18n.global incorrect type when in "composition" mode (should be Composer, is VueI18n)
See original GitHub issueReporting a bug?
This is a TypeScript-related bug.
From the docs https://vue-i18n.intlify.dev/api/general.html#global it is said that “If the I18n#mode is ‘legacy’, then I18n.global
can access to a global VueI18n instance, else then I18n#mode is ‘composition’ , you can access to the global Composer instance.”.
I’ve found this to be true at runtime, but the inferred TypeScript type is always VueI18n
even when in “composition” mode. This throws errors at compile time and in the editor when I try to access Composer properties which are differently typed or absent from VueI18n (according to the mapping found at https://vue-i18n.intlify.dev/guide/advanced/composition.html#mapping-between-vuei18n-instance-and-composer-instance). More on that, this breaks typing on functions that return useI18n() | i18n.global
.
Expected behavior
The following code should not throw a typescript error on the last line
import { createI18n } from "vue-i18n";
const testI18n = createI18n({
legacy: false,
locale: "ja",
fallbackLocale: "en",
messages: {
en: {
message: {
hello: "hello world",
},
},
ja: {
message: {
hello: "こんにちは、世界",
},
},
},
});
const globalComposerInstance = testI18n.global;
console.log(globalComposerInstance.formatter); // this should be absent in Composer instance!
console.log(globalComposerInstance.getMissingHandler); // this should be present is Composer instance!
Instead it throws the following error:
Property 'getMissingHandler' does not exist on type 'VueI18n<{ en: { message: { hello: string; }; }; ja: { message: { hello: string; }; }; }, {}, {}, string, \"ja\" | \"en\", \"ja\" | \"en\", Composer<{ en: { message: { hello: string; }; }; ja: { message: { hello: string; }; }; }, ... 4 more ..., \"ja\" | \"en\">>'.
Reproduction
Use the above snippet anywhere in a project with vue-i18n@9.2.0-beta.28
and typescript@4.5.4
. Hope it is enough, if not i will provide a repro.
System Info
System:
OS: Linux 5.11 Linux Mint 20.2 (Uma)
CPU: (12) x64 Intel(R) Core(TM) i7-10710U CPU @ 1.10GHz
Memory: 843.50 MB / 15.47 GB
Container: Yes
Shell: 5.8 - /usr/bin/zsh
Binaries:
Node: 14.15.0 - ~/.nvm/versions/node/v14.15.0/bin/node
Yarn: 1.22.17 - ~/.nvm/versions/node/v14.15.0/bin/yarn
npm: 8.1.0 - ~/.nvm/versions/node/v14.15.0/bin/npm
Browsers:
Brave Browser: 97.1.34.80
Chrome: 97.0.4692.71
Firefox: 95.0.1
npmPackages:
vue-i18n: ^9.2.0-beta.28 => 9.2.0-beta.28
Screenshot
Additional context
The actual value of testI18n.global
is in fact a Composer instance. The following code:
console.log("testI18n.global", testI18n.global);
console.log("testI18n.global.formatter", testI18n.global.formatter);
logs the following:
Validations
- Read the Contributing Guidelines
- Read the Documentation
- Check that there isn’t already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion
- The provided reproduction is a minimal reproducible example of the bug.
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
I understand that. I thought that
I18n.global
and the returned Composer instance fromuseI18n()
would be the same.For anyone interested, i’ve found a workaround to my use case by double casting
I18n.global
as follows:Problem is solved for me, but I still think that either the docs or the typings should be fixed to work as advised in https://vue-i18n.intlify.dev/api/general.html#global, so I’m leaving this open.
Quoting myself:
Thank you @PeterAlfredLee for your kind patience!
You can pass
schema
andfalse
at the same time, see also this example. Hope this helps.