Vue3 + TypeScript 20 个常见报错

1. Cannot find module 'xxx.vue'

原因: TypeScript 不知道 .vue 文件是什么模块。

改法: 项目根目录加 env.d.ts(或 vite-env.d.ts),并声明:

ts 复制代码
/// <reference types="vite/client" />

若仍报错,检查 tsconfig.jsoninclude 是否包含该声明文件。


2. Property 'xxx' does not exist on type

原因: 模板里用的属性 / 方法在组件里没声明,或类型推断不到。

改法:defineProps / defineEmits 里写类型;ref 用泛型 ref<T>();必要时给 defineExpose 或接口补全类型。


3. ref 取值仍是 undefined 或类型不对

原因: 模板里自动解包,脚本里要用 .value

改法: 脚本中访问 ref 一律 xxx.valuewatch 监听 ref 时可直接写 () => xxx.valuexxx(视写法而定)。


4. Type 'string | undefined' is not assignable to type 'string'

原因: 可选链、可选属性、接口字段带 ?,导致可能是 undefined

改法: 默认值:x ?? '';断言(确定有值时):as string;或把目标类型改成 string | undefined


5. Argument of type 'X' is not assignable to parameter of type 'Y'

原因: 函数参数、事件回调、子组件 emit 的类型和实际传入不一致。

改法: 对齐两边类型;用联合类型;对 unknown 先收窄(typeof / 类型守卫)再使用。


6. Object is possibly 'null' / 'undefined'

原因: 严格空值检查下,编译器认为可能为空。

改法: 可选链 ?.、空值合并 ??;或 if (x != null) 收窄后再用。


7. 模板里组件报红:Component is not resolved

原因: 组件未导入、未全局注册,或名称与标签不一致。

改法: <script setup>import 后直接使用;或检查 components: { ... } 与模板标签名是否一致。


8. defineProps / defineEmits 只能在 <script setup> 顶层使用

原因: 宏只能在编译期、顶层调用,不能放在函数或条件里。

改法:definePropsdefineEmits 挪到 <script setup> 最外层。


9. withDefaults(defineProps<...>(), { ... }) 默认值类型报错

原因: 泛型里必填属性与 withDefaults 里"有默认值"冲突,或类型写法不兼容。

改法: 把有默认值的属性在接口里标成可选 ?;或分开写 Props 与默认值对象,保证类型一致。


10. emit 事件名与类型不匹配

原因: defineEmits 的类型字面量和实际 emit('name', payload) 不一致。

改法: 使用元组形式写 payload,例如:

ts 复制代码
const emit = defineEmits<{
  change: [id: number]
  close: []
}>()

11. v-modelmodelValue / update:modelValue 对不上

原因: Vue 3 默认 v-model 对应 modelValueupdate:modelValue;自定义名字要用 v-model:xxx

改法: 子组件 defineProps 里声明 modelValueemit('update:modelValue', val);具名则 foo + update:foo


12. useRouter / useRoute 在错误位置调用

原因: 组合式 API 必须在 setup<script setup> 同步执行阶段调用(或符合插件要求的上下文)。

改法: 不要在异步回调里首次调用 useRouter;应先在 setup 里取出 router / route 再传入。


13. Pinia:storeToRefs 解构后失去响应式

原因: 直接解构 store 会丢掉响应式。

改法: 状态用 storeToRefs(store),方法仍从 store 上取。


14. import.meta.env 报类型错误

原因: 未扩展 ImportMetaEnv 接口。

改法:env.d.tsinterface ImportMetaEnv { readonly VITE_XXX: string },并扩展 ImportMeta


15. 第三方库没有类型:Could not find a declaration file

原因: 包未自带 @types/xxx

改法: 安装 @types/包名;或自建 xxx.d.tsdeclare module '包名';最差用 // @ts-expect-error 并注明原因。


16. this 相关报错(在 <script setup> 里)

原因: 组合式 API 里没有选项式里的 this

改法:ref / computed / 函数闭包代替 this.xxx;需要实例时用 getCurrentInstance()(尽量少用,优先显式传参)。


17. 异步组件 / defineAsyncComponent 类型推断差

原因: 动态 import 返回类型较宽。

改法: 给变量显式标注组件类型,或对 resolve 结果 as DefineComponent<...>(按项目规范取舍)。


18. Readonly<Array> 不能赋给 Mutable 数组

原因: props 在运行时只读,类型上常推断为 readonly。

改法: 不要原地改 props;需要副本时用 [...arr]arr.slice() 再改。


19. 模板 ref 与脚本 ref 重名或拿不到 DOM

原因: 模板 ref 与变量名冲突,或 DOM 尚未挂载就读取。

改法: 改名区分;在 onMounted 或使用 nextTick 后再访问模板 ref。


20. 构建通过但 IDE 仍红线(或相反)

原因: IDE 用的 TypeScript 版本与 vue-tsc / Vite 不一致;或只检查了部分目录。

改法: 工作区选用项目内的 TypeScript;统一 tsconfiginclude / references;Vue 文件用 Volar(Vue - Official)并禁用旧 Vetur。


小结

方向 建议
类型 props / emit 用泛型写全;少用 any,必要时再收窄
响应式 脚本里记牢 .value;Pinia 用 storeToRefs
工程 env.d.ts + tsconfig 包含范围 + 与构建工具一致

有新报错时,优先看完整 TS 报错栈和行号,再对照上表关键词检索即可。

  • 想学完整的后台管理系统实战?点击订阅我的专栏
相关推荐
阿正的梦工坊2 小时前
JavaScript 微任务与宏任务完全指南
开发语言·javascript·ecmascript
2301_799073026 小时前
基于 Next.js + 火山引擎 AI 的电商素材智能生成工具实战——字节跳动前端训练营成果
javascript·人工智能·火山引擎
RNEA ESIO6 小时前
PHP进阶-在Ubuntu上搭建LAMP环境教程
开发语言·ubuntu·php
geinvse_seg7 小时前
中小团队如何低成本搭建项目管理系统?基于 Ubuntu 的 Dootask 私有化部署实战
linux·运维·ubuntu
丶伯爵式7 小时前
Ubuntu 24.04 更换国内软件源指南 | 2026年3月26日
linux·运维·ubuntu·国内源·升级
算是难了8 小时前
Nestjs学习总结_3
前端·typescript·node.js
kyriewen118 小时前
项目做了一半想重写?这套前端架构让你少走3年弯路
前端·javascript·chrome·架构·ecmascript·html5
EaseUI10 小时前
【Ease UI】2026-04-16 组件更新:新增组件 xly-flow-designer 流程设计器 基于warm-flow二次开发
typescript·前端框架·流程设计器·组件库·warmflow
爱折腾的军哥10 小时前
首发 | OpenTaiji WFGY 防幻觉系统:让 AI Agent 不再"胡说八道"
javascript
颜酱10 小时前
从零实现「拍照记单词」小应用(可复刻版)
前端·javascript·人工智能