I developed a controller
plugin to be used globally in all components, but I am facing challenges making it compatible with Vue 3 + TypeScript + Composition API as I keep getting a TypeScript error.
ui/plugins/controllers.ts
import { App } from 'vue'
import { provider, IProvider } from '@/core/presentation/provider'
export default {
install: (app: App) => {
const controllers: IProvider = provider()
app.provide('controllers', controllers)
}
}
main.ts
import { createApp } from 'vue'
import { controllers } from './ui'
createApp(App)
.use(controllers)
.mount('#app')
@/core/presentation/provider/provider.ts
import { UserController } from '../controllers'
import { IProvider } from './provider.types'
export const provider = (): IProvider => ({
users: new UserController()
})
ui/views/Component.vue
import { onMounted, ref, inject, defineComponent } from 'vue'
export default defineComponent({
setup() {
const controllers = inject('controllers')
const user = ref()
const getUser = async () => {
const result = await controllers.users.getById(1)
if (result) {
user.value = result.toJson()
}
}
onMounted(getUser)
return {
user,
getUser
}
}
})
While trying to utilize the controller, I encounter a typescript error at this particular line
const result = await controllers.users.getById(1)
Error:
const controllers: unknown Object is of type 'unknown'.Vetur(2571)
When attempting to set the type using my interface, it triggers another TypeScript error
import { IProvider } from '@/core'
...
const controllers: IProvider = inject('controllers')
Error:
type 'IProvider | undefined' is not assignable to type 'IProvider'. Type 'undefined' is not assignable to type 'IProvider'.Vetur(2322)
The only way that seems to work for me is by doing this which I find quite unconventional:
const controllers: IProvider | undefined = inject('controllers')
...
const result = await controllers?.users.getById(1)