
1. Cannot find module 'xxx.vue'
原因: TypeScript 不知道 .vue 文件是什么模块。
改法: 项目根目录加 env.d.ts(或 vite-env.d.ts),并声明:
ts
/// <reference types="vite/client" />
若仍报错,检查 tsconfig.json 的 include 是否包含该声明文件。
2. Property 'xxx' does not exist on type
原因: 模板里用的属性 / 方法在组件里没声明,或类型推断不到。
改法: 在 defineProps / defineEmits 里写类型;ref 用泛型 ref<T>();必要时给 defineExpose 或接口补全类型。
3. ref 取值仍是 undefined 或类型不对
原因: 模板里自动解包,脚本里要用 .value。
改法: 脚本中访问 ref 一律 xxx.value;watch 监听 ref 时可直接写 () => xxx.value 或 xxx(视写法而定)。
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> 顶层使用
原因: 宏只能在编译期、顶层调用,不能放在函数或条件里。
改法: 把 defineProps、defineEmits 挪到 <script setup> 最外层。
9. withDefaults(defineProps<...>(), { ... }) 默认值类型报错
原因: 泛型里必填属性与 withDefaults 里"有默认值"冲突,或类型写法不兼容。
改法: 把有默认值的属性在接口里标成可选 ?;或分开写 Props 与默认值对象,保证类型一致。
10. emit 事件名与类型不匹配
原因: defineEmits 的类型字面量和实际 emit('name', payload) 不一致。
改法: 使用元组形式写 payload,例如:
ts
const emit = defineEmits<{
change: [id: number]
close: []
}>()
11. v-model 与 modelValue / update:modelValue 对不上
原因: Vue 3 默认 v-model 对应 modelValue 和 update:modelValue;自定义名字要用 v-model:xxx。
改法: 子组件 defineProps 里声明 modelValue,emit('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.ts 里 interface ImportMetaEnv { readonly VITE_XXX: string },并扩展 ImportMeta。
15. 第三方库没有类型:Could not find a declaration file
原因: 包未自带 @types/xxx。
改法: 安装 @types/包名;或自建 xxx.d.ts:declare 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;统一 tsconfig 的 include / references;Vue 文件用 Volar(Vue - Official)并禁用旧 Vetur。
小结
| 方向 | 建议 |
|---|---|
| 类型 | props / emit 用泛型写全;少用 any,必要时再收窄 |
| 响应式 | 脚本里记牢 .value;Pinia 用 storeToRefs |
| 工程 | env.d.ts + tsconfig 包含范围 + 与构建工具一致 |
有新报错时,优先看完整 TS 报错栈和行号,再对照上表关键词检索即可。
- 想学完整的后台管理系统实战?点击订阅我的专栏