Search code examples
typescriptvue.jsvue-clivue-i18n

Why my fresh vue3 project generated with Vue-cli in Typescript with vue-cli-i18n isn't working out of the box?


I hope you can help me. I'm new on vue/i18n and others, so sorry if the response is simple or already exists where else, but I didn't find it ......

I try to generate a new project using vue-cli and vue-cli-plugin-i18n but the resulting source code of this isn't building...

Let me explain I generate a fresh vue project with vue-cli in typescript like this like this the configuration while using vue-cli

then, I try to add the i18n plugin to this new project with the command 'vue add i18n@next' and select these options the configuration while adding i18n to the previous project

this is the content of my packagess.json file

{
  "name": "my-vue-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "i18n:report": "vue-cli-service i18n:report --src \"./src/**/*.?(js|vue)\" --locales \"./src/locales/**/*.json\""
  },
  "dependencies": {
    "register-service-worker": "^1.7.2",
    "vue": "^3.2.13",
    "vue-i18n": "^9.1.0",
    "vue-router": "^4.0.3",
    "vuex": "^4.0.0"
  },
  "devDependencies": {
    "@intlify/vue-i18n-loader": "^2.1.0",
    "@typescript-eslint/eslint-plugin": "^5.4.0",
    "@typescript-eslint/parser": "^5.4.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-plugin-pwa": "~5.0.0",
    "@vue/cli-plugin-router": "~5.0.0",
    "@vue/cli-plugin-typescript": "~5.0.0",
    "@vue/cli-plugin-vuex": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "@vue/eslint-config-typescript": "^9.1.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "typescript": "~4.5.5",
    "vue-cli-plugin-i18n": "^2.1.1"
  }
}

And the content of my i18n.ts generated file

import { createI18n, LocaleMessages, VueMessageType } from 'vue-i18n'

/**
 * Load locale messages
 * 
 * The loaded `JSON` locale messages is pre-compiled by `@intlify/vue-i18n-loader`, which is integrated into `vue-cli-plugin-i18n`.
 * See: https://github.com/intlify/vue-i18n-loader#rocket-i18n-resource-pre-compilation
 */
function loadLocaleMessages(): LocaleMessages<VueMessageType> {
  const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
  const messages: LocaleMessages<VueMessageType> = {}
  locales.keys().forEach(key => {
    const matched = key.match(/([A-Za-z0-9-_]+)\./i)
    if (matched && matched.length > 1) {
      const locale = matched[1]
      messages[locale] = locales(key)
    }
  })
  return messages
}

export default createI18n({
  legacy: false,
  locale: process.env.VUE_APP_I18N_LOCALE || 'en',
  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
  messages: loadLocaleMessages()
})

But finally, when I run an npm run serve command, I have this error

ERROR in src/i18n.ts:26:3
TS2769: No overload matches this call.
  Overload 1 of 2, '(options: I18nOptions<{ message: LocaleMessage<VueMessageType>; datetime: DateTimeFormat; number: NumberFormat; }, string, ComposerOptions<{ ...; }, ... 9 more ..., NumberFormats<...>> | VueI18nOptions<...>>, LegacyVueI18n?: any): I18n<...>', gave the following error.
    Type 'LocaleMessages<VueMessageType, string, string>' is not assignable to type '{ [x: string]: LocaleMessage<VueMessageType>; }'.
      'string' index signatures are incompatible.
        Type 'VueMessageType' is not assignable to type 'LocaleMessage<VueMessageType>'.
          Type 'string' is not assignable to type 'LocaleMessage<VueMessageType>'.
  Overload 2 of 2, '(options: I18nOptions<{ message: LocaleMessage<VueMessageType>; datetime: DateTimeFormat; number: NumberFormat; }, { messages: "en-US"; datetimeFormats: "en-US"; numberFormats: "en-US"; }, ComposerOptions<...> | VueI18nOptions<...>>, LegacyVueI18n?: any): I18n<...>', gave the following error.
    Property '"en-US"' is missing in type 'LocaleMessages<VueMessageType, string, string>' but required in type '{ "en-US": LocaleMessage<VueMessageType>; }'.
    24 |   locale: process.env.VUE_APP_I18N_LOCALE || 'en',
    25 |   fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
  > 26 |   messages: loadLocaleMessages()
       |   ^^^^^^^^
    27 | })
    28 |

Thanks for your time and your help.

node version => v16.17.1 npm version => 8.15.0


Solution

  • I was having the same error and I solved it changing the type to the one that the error message says it is expected.

    import { createI18n, LocaleMessages, VueMessageType } from 'vue-i18n'
    
    function loadLocaleMessages(): { [x: string]: LocaleMessages<VueMessageType> } {
      const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
      const messages: { [x: string]: LocaleMessages<VueMessageType> } = {}
      locales.keys().forEach(key => {
        const matched = key.match(/([A-Za-z0-9-_]+)\./i)
        if (matched && matched.length > 1) {
          const locale = matched[1]
          messages[locale] = locales(key).default
        }
      })
      return messages
    }
    
    export default createI18n({
      legacy: false,
      locale: process.env.VUE_APP_I18N_LOCALE || 'en',
      fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
      messages: loadLocaleMessages()
    })