P
P
Peter Sergeev2022-03-24 20:29:44
typescript
Peter Sergeev, 2022-03-24 20:29:44

What should be the type of inject in vue 3 when using typescript?

There is a translation functionality using provide / inject
If you specify the type any, then everything works, but what should be the correct type?

This is the component where the localizeFilter function is injected into which the string key is passed, by which the word in a certain language is returned.
The messagePlagin is now set to type any, as there are no errors with it.

<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>


This code is the implementation of provide.
In fact, there are also problems with types that I have not yet been able to solve (you can understand from the commented eslint lines))), but this is probably another question

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)
  }
}


To summarize, how to set a type other than any in messagePlagin when using inject

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Oleg Barabanov, 2022-03-25
@223606322

To store the type, when using provide/inject as a key, you must use InjectionKey<T>. This point is described in the Vue3 documentation on using inject/provide, namely:

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().

Those. in your case, you can create something like injection-keys.ts:
import {InjectionKey} from 'vue';
// InjectionKey<T>, где T представляет явно передаваемый тип,  который отслеживается при provide/inject
export const localizeFilterKey: InjectionKey<(key: string) => string> = Symbol();

And then import this file wherever inject/provide is used with the necessary keys.
In the case of using provide:
import localizeFilterKey from '@/injection-keys'
...
    app.provide(localizeFilterKey, localizeFilterKey)
...

and accordingly in the case of using inject:
import localizeFilterKey from '@/injection-keys'
...
    const messagePlagin = inject(localizeFilterKey);
...

The examples are oversimplified, but I hope this helps you.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question