一、前言
进入 TypeScript 阶段。前面 39 篇全用 JS 是为了降低门槛,但企业项目的新建 Vue3 项目基本都选 TS ------从这篇起,代码切换到 <script setup lang="ts">,前面学的所有知识不需要重学,只是"穿上类型这件防护服"。本篇从零建一个 Vue3 + TS 工程,讲清目录变化和 tsconfig 关键项。
二、创建项目:一行命令 + 问卷
bash
npm create vue@latest my-vue-app
这是官方脚手架 create-vue(底层就是 Vite),回车后出现问卷:
text
✔ Project name: ... my-vue-app
✔ Add TypeScript? ... 是 ← 本篇主角,必须选
✔ Add JSX Support? ... 否
✔ Add Vue Router? ... 否 ← 路由篇再选,先手动学
✔ Add Pinia? ... 否 ← Pinia 篇再选
✔ Add Vitest / E2E / ESLint / Prettier ... 按需,新手可全否
小贴士:赶时间的同学可以 TS + Router + Pinia 全选直接生成企业骨架;但为了学习效果,建议只选 TS,Router 和 Pinia 后面篇目手动装一遍,知其所以然。
bash
cd my-vue-app
npm install
npm run dev
三、目录变化:和 JS 版差在哪
text
my-vue-app/
├── src/
│ ├── main.ts ← main.js 变成了 main.ts
│ ├── App.vue
│ ├── components/
│ │ └── HelloWorld.vue ← script 标签多了 lang="ts"
│ └── assets/
├── env.d.ts ← 新增!告诉 TS 那些"非 TS 文件"是什么
├── index.html
├── package.json
├── tsconfig.json ← 新增!TS 总配置(可能引用下面两个)
│ ├── tsconfig.app.json ← 新增!管 src 源码的编译选项
│ └── tsconfig.node.json ← 新增!管 vite.config.ts 的编译选项
└── vite.config.ts ← vite.config.js 也变 TS 了
三个新文件各自干什么:
- env.d.ts :内容是
/// <reference types="vite/client" />,让 TS 认识 import.meta.env 等 Vite 特性。旧版模板它可能在 src 下,位置随版本略有不同,功能一致 - tsconfig.json:总入口,用"引用"把配置拆给 app/node 两份------源码一套规则、配置文件一套规则,互不干扰
- tsconfig.app.json :你以后改的主要是它(比如配 @ 别名)
.vue 文件 TS 怎么认识?靠 Volar (插件全名 Vue - Official,003 篇装过)+ vue-tsc 组合:编辑器类型提示靠 Volar,命令行类型检查靠 vue-tsc。
四、type-check:Vite 不检查类型,vue-tsc 才查
看 package.json 的 scripts:
json
{
"scripts": {
"dev": "vite",
"type-check": "vue-tsc --build",
"build": "run-p type-check \"build-only {@}\"",
"preview": "vite preview"
}
}
一个必须建立的心智 :npm run dev 和 vite build 都不做类型检查(Vite 用 esbuild 转译 TS,只剥掉类型不校验)。真正的类型关卡是:
- 开发时:VS Code 里 Volar 的红色波浪线(编辑器实时提示)
- 构建时:
npm run build会先跑type-check(vue-tsc),类型不过直接构建失败
所以"明明 dev 能跑,build 却报错"不是玄学------dev 根本没查类型。
五、tsconfig 关键项速览
打开 tsconfig.app.json,重点认识这几项(脚手架已配好,会看就行):
jsonc
{
"compilerOptions": {
"target": "ES2020", // 编译目标的 JS 版本
"module": "ESNext",
"moduleResolution": "bundler", // 按打包器方式解析模块(Vite 专用,别改成 node)
"strict": true, // ★ 严格模式全家桶,报错多但护你周全,别关
"noUnusedLocals": true, // 未使用的变量报错
"noUnusedParameters": true, // 未使用的参数报错
"skipLibCheck": true, // 跳过 node_modules 里的类型检查(提速)
"jsx": "preserve",
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] } // ★ @ 别名的 TS 侧配置
},
"include": ["src/**/*.ts", "src/**/*.vue"]
}
记忆优先级:strict 别动、paths 配别名、moduleResolution 保持 bundler,其余用到再查。
六、配置 @ 别名:TS 侧和 Vite 侧都要配
JS 阶段(003 篇)配过 Vite 侧的别名,TS 项目要两边一起配,缺一边就一边红:
1. Vite 侧(vite.config.ts)------管"构建时路径能不能找到":
ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
2. TS 侧(tsconfig.app.json)------管"编辑器里 import 会不会红线":
jsonc
{
"compilerOptions": {
// ...其他选项
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
配完重启编辑器的 TS 服务(VS Code:Ctrl+Shift+P → Restart TS Server / 重启 TS 服务器),import xxx from '@/components/Xxx.vue' 两边都绿。
七、第一个 TS 组件:感受一下类型的存在
vue
<!-- src/components/HelloTs.vue -->
<template>
<p>用户:{{ user.name }},年龄:{{ user.age }}</p>
<p>列表共 {{ list.length }} 项</p>
</template>
<script setup lang="ts">
// 注意 script 标签:lang="ts" 从此常驻
import { ref, reactive } from 'vue'
// 接口:描述数据长什么样
interface User {
name: string
age: number
}
const user = reactive<User>({ name: '小明', age: 18 })
// ref 会自动推断类型:list 被推断为 Ref<string[]>
const list = ref(['Vue', 'TS'])
// ❌ 试试点开注释,编辑器立刻红线(dev 仍能跑,但类型不过关)
// user.age = '十八'
</script>
把 user.age = '十八' 的注释打开:页面照常运行 (dev 不查类型),但编辑器红线、build 失败------这就是 TS 的价值:把运行时才炸的 bug 提前到写代码的那一刻。类型语法的详细规则下一篇展开。
【截图位置:user.age 赋值字符串时编辑器红线的截图】
八、踩坑记录
- 报"找不到模块 './App.vue'" :老教程让你手写
declare module '*.vue'------新版脚手架 + Volar 不需要;出现该报错先重启 TS 服务,再检查 Volar 插件是否装了官方版(Vue - Official,旧名 Volar) - @ 别名一边绿一边红:只配了 vite.config 或只配了 tsconfig------必须两侧同配(第六节)
- tsconfig 里加错文件:paths 加到了 tsconfig.node.json(那是给 vite.config.ts 用的)------源码别名加在 tsconfig.app.json
- build 报类型错误但 dev 正常 :第四节的心智------dev 不查类型,以
npm run type-check为准修复 - 装依赖用错包名 :脚手架命令是
npm create vue@latest,不是npm create vite@latest后手动拼 ts 模板(旧 vite vue-ts 模板已被官方边缘化)
九、今日小结
npm create vue@latest问卷选 TS;新增 env.d.ts、tsconfig 三件套- dev/preview 不查类型,
vue-tsc(type-check/build)才是关卡 - tsconfig 记三条:strict 别关、paths 配别名、moduleResolution 保持 bundler
- @ 别名 Vite 侧 + TS 侧双配置;.vue 的类型识别靠 Vue - Official 插件 + vue-tsc
下篇预告
interface、Ref<T>、泛型标注......TS 在响应式数据上的全部写法:ref 怎么标类型?reactive 和 interface 怎么配?返回值类型怎么声明?下一篇 041 ref 与 reactive 的 TS 类型标注。