VueJS计算属性内访问其他计算属性报属性不存在错误
Vue计算属性互访报类型不存在问题解答
问题复现
开发场景下需要通过计算属性提取路由URL中的id参数,初始实现代码如下:
export default defineComponent({ computed: { extractionId() : string { return this.$route.params.id as string; }, releves() { let extractionId = this.extractionId; return this.$store.getters.getExtractionById(extractionId) } }, // ....
在releves计算属性中访问this.extractionId时,抛出如下TypeScript报错:
Property 'extractionId' doesn't exist on type 'CreateComponentPublicInstance<{ [x: `on${string}`]: ((...args: any[]) => any) | undefined; } | { [x: `on${string}`]: ((...args: never) => any) | undefined; }, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, ... 10 more ..., {}>'.
核心结论
Vue 本身完全允许计算属性之间互相依赖引用,该报错不是Vue语法规则限制,是TypeScript对组件实例类型推导失败导致的类型校验错误,和Vue运行时逻辑无关。
只要计算属性之间不存在循环依赖(比如A依赖B的同时B依赖A),互访就是Vue的合法标准用法。
报错原因
在使用defineComponent编写TS组件时,如果给单个计算属性函数显式标注返回值类型,会打断TS对整个computed选项的类型推导链,导致TS无法将已定义的其他计算属性挂载到组件实例的this类型上,最终抛出属性不存在的错误。
解决方案
最简便的修复方式是去掉计算属性函数上的显式返回类型标注,将类型断言写在返回值内部,让TS自动完成整个computed块的类型推导即可,修复后的代码如下:
export default defineComponent({ computed: { extractionId() { // 类型断言直接写在返回值位置,无需给函数本身标注返回类型 return this.$route.params.id as string; }, releves() { const extractionId = this.extractionId; return this.$store.getters.getExtractionById(extractionId) } }, // 其余组件逻辑 })
如果确实需要给计算属性显式标注返回类型,也可以通过以下两种方式处理:
- 升级Vue、vue-router到对应大版本的最新稳定版,新版本已经修复了多数这类类型推导边界问题
- 在访问计算属性时临时给
this做类型断言,不过这种方式写法冗余,不推荐优先使用
内容的提问来源于stack exchange,提问作者bachrc
相关产品推荐
相关产品推荐

