Vue2升级Vue3后类组件中$store/$t触发TS类型错误
Vue3兼容模式下vue-facing-decorator类组件TS报错$store/$t不存在的解决办法
问题场景
Vue2升级到Vue3兼容模式后,应用运行正常,Vuex和i18n功能都能正常工作,但使用vue-facing-decorator的类语法编写组件时,TypeScript会提示$store和$t不存在;而用传统选项式语法编写时则无此错误。
类组件报错代码示例:
import { Component, Vue } from 'vue-facing-decorator'; @Component export class TopBar extends Vue { myMethod() { this.$store.getters['session/abc']; // TS错误:Property '$store' does not exist on type 'TopBar' } }
选项式无错误代码示例:
export default { methods: { myMethod() { this.$store.getters['session/abc']; // 无错误 } } }
当前使用的shim.d.ts内容:
export {}; declare module 'vue' { import { CompatVue } from 'vue'; const Vue: CompatVue; export default Vue; // eslint-disable-next-line vue/prefer-import-from-vue export * from '@vue/runtime-dom'; const { configureCompat } = Vue; export { configureCompat }; }
问题原因
选项式语法能自动识别全局属性,是因为Vue3的ComponentCustomProperties接口会合并到选项式组件的this类型中。但vue-facing-decorator的类组件继承的是它自身导出的Vue类,现有类型声明没有把$store、$t这类全局属性合并到这个类的类型上,导致TypeScript无法识别。
解决步骤
修改shim.d.ts文件,补充$store和$t的类型声明,同时覆盖vue-facing-decorator的Vue类类型:
export {}; // 导入对应类型,根据项目实际情况调整 import { Store } from 'vuex'; import type { RootState } from './src/store'; // 替换为你项目的Store根状态类型路径 import type { TranslateFunction } from 'vue-i18n'; declare module 'vue' { import { CompatVue } from 'vue'; const Vue: CompatVue; export default Vue; export * from '@vue/runtime-dom'; const { configureCompat } = Vue; export { configureCompat }; // 扩展Vue实例的全局属性 interface ComponentCustomProperties { $store: Store<RootState>; $t: TranslateFunction; } } // 给vue-facing-decorator的Vue类扩展类型 declare module 'vue-facing-decorator' { import { Vue } from 'vue-facing-decorator'; interface Vue { $store: Store<RootState>; $t: TranslateFunction; } }
临时替代方案(若未定义RootState)
如果项目还没补全Store的根状态类型,可以先用any临时过渡(建议尽快补全类型以获得完整TS提示):
// 替换上述的ComponentCustomProperties和vue-facing-decorator中的类型定义 interface ComponentCustomProperties { $store: Store<any>; $t: (key: string, ...args: any[]) => string; } declare module 'vue-facing-decorator' { import { Vue } from 'vue-facing-decorator'; interface Vue { $store: Store<any>; $t: (key: string, ...args: any[]) => string; } }
额外检查
确保tsconfig.json的include数组包含了shim.d.ts文件:
{ "include": [ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue" ] }
内容的提问来源于stack exchange,提问作者coure2011
相关产品推荐
相关产品推荐

