@223606322
начинающий web-разработчик

Какой должен быть тип у inject во vue 3 при использовании typescript?

Есть функционал перевода при помощь provide/inject
Если указать тип any, то все работает, но какой все же правильный тип должен быть?

Это компонент куда inject-тируется функция localizeFilter в которую передается строковый ключ по которому возвращается слово на определенном языке.
Сейчас у messagePlagin задан тип any, так как с ним ошибок нет.
<script lang="ts">
import { inject, computed } from 'vue'

export default {
  props: ['modelValue'],
  setup() {
    const messagePlagin: any = inject('localizeFilter')
    const links = computed(() => {
      return [
        { title: messagePlagin('Bill'), url: '/' },
        { title: messagePlagin('History'), url: '/history' },
        { title: messagePlagin('Planning'), url: '/planning' },
        { title: messagePlagin('Record'), url: '/record' },
        { title: messagePlagin('Categories'), url: '/categories' }
      ]
    })

    return {
      links
    }
  }
}
</script>


Этот код представляет из себя реализацию provide.
На самом деле тут тоже есть проблемы с типами, которые я еще не смог решить(по закомментированным eslint строкам можете понять))), но это наверное другой вопрос

import { store, key } from '@/store'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import ru from '@/locales/ru.json'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import en from '@/locales/en.json'

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $localizeFilter: (text: string) => string
  }
}

const locales = {
  'ru-RU': ru as string,
  'en-US': en as string
}

export default {
  install(app: any, options: any) {
    const localizeFilter = app.config.globalProperties.$localizeFilter = (key: string) => {
      const locale = store.getters['info/info'].locale || 'ru-RU' as string

      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      return locales[locale][key] || `[Localize error]: key ${key} not found`
    }

    app.provide('localizeFilter', localizeFilter)
  }
}


Подводя итог, как задать тип кроме any в messagePlagin при ипользовании inject
  • Вопрос задан
  • 1108 просмотров
Решения вопроса 1
olegbarabanov
@olegbarabanov
Программист, фрилансер (ИП)
Для сохранения типа, при использовании provide/inject в виде ключа необходимо использовать InjectionKey<T>. Этот момент описан в документации Vue3 по применению inject/provide, а именно:
When using TypeScript, the key can be a symbol casted as InjectionKey - a Vue provided utility type that extends Symbol, which can be used to sync the value type between provide() and inject().

Т.е. в вашем случае, вы можете создать что-то подобие injection-keys.ts:
import {InjectionKey} from 'vue';
// InjectionKey<T>, где T представляет явно передаваемый тип,  который отслеживается при provide/inject
export const localizeFilterKey: InjectionKey<(key: string) => string> = Symbol();

А потом импортировать этот файл везде, где используется inject/provide с необходимыми ключами.
В случае с применением provide:
import localizeFilterKey from '@/injection-keys'
...
    app.provide(localizeFilterKey, localizeFilter)
...

и соответственно в случае с применением inject:
import localizeFilterKey from '@/injection-keys'
...
    const messagePlagin = inject(localizeFilterKey);
...


Примеры сильно упрощенные, но надеюсь это сможет вам помочь.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы