Nuxt 2 + TypeScript报错:Property 'xxx' does not exist on type '{}'
解决Nuxt 2.15.8中TypeScript + Composition API的TS(2339)及运行时未定义问题
一、核心问题定位
这是Nuxt 2的Composition API适配TypeScript时的类型声明缺失,以及Composition API下fetch钩子的使用逻辑和Options API不一致,导致$fetchState失效、数据未挂载到实例引发的问题。
二、分步解决方案
1. 补全TypeScript类型声明
Nuxt 2的Composition API需要额外扩展全局属性和组件实例的类型,才能让TS识别$fetchState等属性:
- 在项目根目录创建
types/shims-vue.d.ts文件,添加以下内容:import { ComponentCustomProperties } from 'vue' import { FetchState } from '@nuxtjs/composition-api' declare module '@vue/runtime-core' { interface ComponentCustomProperties { $fetchState: FetchState // 有其他全局属性也可在此扩展 } } - 修改
tsconfig.json,确保类型文件被正确识别:{ "compilerOptions": { "types": [ "@nuxt/types", "@nuxtjs/composition-api" ], "typeRoots": ["./types", "./node_modules/@types"] }, "include": [ "**/*.ts", "**/*.vue", "types/**/*.d.ts" ] }
2. 修正Composition API下的fetch使用方式
Nuxt 2的Composition API不能直接用Options API的$fetchState写法,必须使用useFetch钩子:
<template> <div v-if="$fetchState.pending">加载中...</div> <div v-else-if="$fetchState.error">加载失败</div> <div v-else>{{ exam }}</div> </template> <script lang="ts"> import { defineComponent, useFetch, ref } from '@nuxtjs/composition-api' export default defineComponent({ setup() { const exam = ref(null) // 用useFetch替代Options API的fetch钩子 useFetch(async () => { // 替换为你的实际请求逻辑 const res = await fetch('/api/exam') exam.value = await res.json() }) // 必须return模板要用到的变量,否则运行时会提示未定义 return { exam } } }) </script>
注意:useFetch返回的fetchState会自动挂载到组件实例的$fetchState上,同时响应式变量必须通过return暴露给模板。
3. 确保依赖版本兼容
安装与Nuxt 2.15.8匹配的@nuxtjs/composition-api版本,推荐^0.33.1:
npm install @nuxtjs/composition-api@^0.33.1 --save
然后在nuxt.config.js中注册模块:
export default { modules: ['@nuxtjs/composition-api/module'], // 其他配置... }
4. 清除缓存重启服务
Nuxt的类型缓存可能导致配置不生效,执行以下命令:
rm -rf node_modules/.cache npm run dev
三、常见误区排查
- 不要在
setup中使用this,所有变量和方法都要通过Composition API的钩子获取。 - 模板中用到的变量必须在
setup中return,否则运行时会提示未定义。 - 不要混合Options API和Composition API的
fetch写法,二者逻辑不兼容。
内容的提问来源于stack exchange,提问作者Seangle
相关产品推荐
相关产品推荐

