typescript - 带有组合 API 和 TypeScript 的 Vue 3 注入插件
问题描述
我创建了一个controller
在每个组件中全局使用的插件,但我无法使其与 Vue 3 + TypeScript + Composition API 一起使用我收到 TypeScript 错误
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
}
}
})
在这里,当我尝试在此行使用控制器时出现打字稿错误
const result = await controllers.users.getById(1)
错误:
const controllers: unknown Object is of type 'unknown'.Vetur(2571)
如果我像这样使用我的界面设置类型,我会收到另一个打字稿错误
import { IProvider } from '@/core'
...
const controllers: IProvider = inject('controllers')
错误:
type 'IProvider | undefined' is not assignable to type 'IProvider'. Type 'undefined' is not assignable to type 'IProvider'.Vetur(2322)
我只能让它像这样工作,但我认为这很奇怪:
const controllers: IProvider | undefined = inject('controllers')
...
const result = await controllers?.users.getById(1)
解决方案
我设法通过发布Type-safe Vue.js Injections解决了我的问题
需要注意的一件事是,inject函数会生成与 结合的已解析类型
undefined
。这是因为存在注入未解决的可能性。这取决于你想如何处理它。
所以为了应对,undefined
我听从了他的建议并创建了一个injectStrict
函数。这是我的最终代码:
组件.vue
import { IProvider } from '@/core'
import { injectStrict } from '@/ui/utils'
import { onMounted, ref, defineComponent } from 'vue'
export default defineComponent({
setup() {
const controllers: IProvider = injectStrict('controllers')
const user = ref()
const getUser = async () => {
const result = await controllers.users.getById(1)
if (result) {
user.value = result.toObj()
}
}
onMounted(getUser)
return {
user,
getUser
}
}
})
@/utils/injections.ts
import { inject } from 'vue'
function injectStrict<T>(key: string, fallback?: T) {
const resolved = inject(key, fallback)
if (!resolved) {
throw new Error(`Could not resolve ${key}`)
}
return resolved
}
export { injectStrict }
推荐阅读
- go - 将 CSV 解组为 Struct 然后导入
- python - 如何在 Python 中实现动态序列(例如“几何范围”)?
- r - tm_map: 可以使用 removewords 函数将我自己的停用词注册为 txt 文件吗?
- php - 服务器发送事件不断重启新请求
- php - utf emoji 的 json 解码如何实现?
- python - 如何使用换行符写入文件并避免空行
- python - 无法从 S3 获取 csv 并使用 Python 进行转换
- vue.js - vue.js 中的数组属性
- reactjs - 如何防止 Material UI Dialog 在单击背景时被关闭?
- python - 安装 matplotlib 时 pip install 命令错误,退出状态为 1