«Свойство ‘$i18n’ не существует для типа X» в приложении Nuxt

#typescript #vue.js #nuxt.js

Вопрос:

Я пишу приложение Nuxt на машинописном языке. Я столкнулся с проблемой при попытке доступа к объекту $i18n в Nuxt. Я получаю предупреждение в коде VS, в котором говорится::

 Property '$i18n' does not exist on type 'MyClass'.
 

Моя часть сценария в коде компонента выглядит следующим образом:

 <script lang="ts">
  import { Vue, Component, Prop } from 'vue-property-decorator'
  import ILocale from '~/types/vue/Locales'

  @Component
  export default class MyClass extends Vue {
    @Prop({ type: Boolean, default: true }) showLanguageSwitch!: boolean

    get availableLocales(): ILocale[] {
      return this.$i18n.locales.filter((l) => l.code !== this.$i18n.locale)
    }
  }
</script>
 

У меня есть файл оболочки в корне проекта:

 declare module '*.vue' {
  import Vue from 'vue'
  export default Vue
}
 

Это то место, где я должен расширить интерфейс? Как мне на самом деле это сделать, поскольку Vue это не интерфейс TS, а определение класса со своим собственным типом.

Единственное, что работало до сих пор, — это добавление частной собственности явно MyClass , но затем она жалуется на отсутствие инициализации, и в любом случае это кажется неправильным. Все другие общие свойства Vue распознаются TS, такие как $fetch, $config и т. Д.

Конфигурация TS:

 {
  "compilerOptions": {
    "target": "ES2018",
    "module": "ESNext",
    "moduleResolution": "Node",
    "lib": [
      "ESNext",
      "ESNext.AsyncIterable",
      "DOM"
    ],
    "esModuleInterop": true,
    "allowJs": true,
    "sourceMap": true,
    "strict": true,
    "noEmit": true,
    "experimentalDecorators": true,
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "./*"
      ],
      "@/*": [
        "./*"
      ]
    },
    "types": [
      "@types/node",
      "@nuxt/types"
    ]
  },
  "exclude": [
    "node_modules"
  ]
}
 

Nuxt config:

 export default {
  head: {
    htmlAttrs: {
      lang: 'en',
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' },
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
  },
  publicRuntimeConfig: {},
  css: [
    '~assets/scss/fonts.scss',
    '~assets/scss/variables.scss',
    '~assets/scss/mixins.scss',
    '~assets/scss/reset.scss',
    '~assets/scss/typography.scss',
  ],
  i18n: {
    lazy: true,
    langDir: 'i18n/',
    locales: [
      {
        code: 'en',
        iso: 'en',
        file: 'en.json',
        name: 'English',
      },
      {
        code: 'de-DE',
        iso: 'de-DE',
        file: 'de.json',
        name: 'Deutsch',
      },
    ],
    defaultLocale: 'en',
    vueI18n: {
      fallbackLocale: 'en',
    },
    seo: true,
    strategy: 'prefix_except_default',
  },
  plugins: ['~/plugins/jsonld', '~/plugins/helpers'],
  components: true,
  buildModules: ['@nuxtjs/eslint-module', '@nuxt/typescript-build'],
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/style-resources',
    'nuxt-i18n',
    '@nuxtjs/sitemap',
  ],
  axios: {},
  server: {
    port: 3000,
    host: '0.0.0.0',
  },
  router: {
    middleware: ['langRedirect', 'seoMiddleware'],
    trailingSlash: true,
  },
  serverMiddleware: [
    '~/server-middleware/redirectApex.js',
    { path: '/api', handler: '~/server-middleware/rest.js' },
  ],
  build: {},
  styleResources: {
    scss: [
      '~assets/scss/fonts.scss',
      '~assets/scss/variables.scss',
      '~assets/scss/mixins.scss',
      '~assets/scss/reset.scss',
      '~assets/scss/typography.scss',
    ],
  },
}
 

(РЕДАКТИРОВАТЬ) Исправьте функцию теперь после загрузки nuxt-18n типов:

 get availableLocales(): NuxtVueI18n.Options.LocaleObject[] {
  if (!this.$i18n.locales) {
    return []
  }

  return (this.$i18n.locales as NuxtVueI18n.Options.LocaleObject[]).filter(
    (l) => l.code !== this.$i18n.locale
  )
}
 

Ответ №1:

В tsconfig.json записи добавить "nuxt-i18n" к типам :

     "types": [
      "@types/node",
      "@nuxt/types",
       "nuxt-i18n"
    ]
 

Комментарии:

1. Да, это был тот самый — спасибо, что заметил.