TypeScript提示属性不存在但实际存在?Vue Apollo场景答疑
问题解答
核心原因
useQuery返回的result是一个Ref包装对象,类型为Ref<Accounts | undefined>:
- Ref是Vue实现响应式的容器,必须通过
.value才能访问内部存储的实际数据。直接写result.accounts相当于在Ref对象本身上查找accounts属性,但Ref对象本身并没有这个属性,因此TypeScript抛出TS2339错误。 - 查询未完成时,
result.value的初始值是undefined,这也是类型中包含undefined的原因。
而模板中能直接使用result.accounts,是因为Vue会自动对模板里的Ref对象做解包处理,相当于自动帮你访问了result.value?.accounts(同时通过可选链处理了result.value为undefined的情况)。
解决方案
如果想直接返回accounts而非整个result,需要手动访问Ref的.value,同时处理undefined的情况:
方法1:使用计算属性(推荐,保持响应式)
import { computed } from 'vue'; // ... 其他代码 setup() { const { result, loading, error } = useQuery<Accounts>(ACCOUNTS_QUERY); const accounts = computed(() => result.value?.accounts || []); return { accounts, loading, error }; }
用computed包裹后,accounts会保持响应式,且默认值为空数组,避免模板中出现undefined的问题。
方法2:直接返回可选链访问结果
setup() { const { result, loading, error } = useQuery<Accounts>(ACCOUNTS_QUERY); return { accounts: result.value?.accounts, loading, error }; }
这种方式下accounts可能为undefined,模板中需要额外判断(比如v-if="accounts")后再使用v-for。
内容的提问来源于stack exchange,提问作者Björn Andersson
相关产品推荐
相关产品推荐

