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 报错栈和行号,再对照上表关键词检索即可。

  • 想学完整的后台管理系统实战?点击订阅我的专栏
相关推荐
拾贰_C2 小时前
【Ubuntu | Nvidia | installition0】Ubuntu安装Nvidia驱动
linux·运维·ubuntu
晓13132 小时前
React篇——第五章 React Router实战
开发语言·javascript·ecmascript
不超限2 小时前
InfoSuite AS部署Vue项目
前端·javascript·vue.js
程序员小寒2 小时前
JavaScript设计模式(五):装饰者模式实现与应用
前端·javascript·设计模式
拾贰_C2 小时前
【Ubuntu | 自动联网 | 网络问题】Ubuntu无法自动联网问题
linux·网络·ubuntu
0110编程之路2 小时前
Wine & Ubuntu 调用 Windows 应用
linux·windows·ubuntu
wefly20172 小时前
零基础上手m3u8live.cn,免费无广告的M3U8在线播放器,电脑手机通用
前端·javascript·学习·电脑·m3u8·m3u8在线播放
晓13132 小时前
React篇——第四章 React Router基础
前端·javascript·react
cch89182 小时前
常见布局实现详解(Flex 实战版)
前端·javascript·css