TypeScript快速入门:30分钟上手指南
上周五晚上十点半,我瘫在工位上盯着屏幕上一串 Cannot read property 'name' of undefined 的报错,内心无比崩溃。这已经是本周第三次因为 JS 的“灵活”特性导致线上 bug 了。产品经理还在群里@我:“这个页面怎么又白屏了?明天早上要给客户演示啊!”
那一刻,我终于下定决心:必须把项目从 JavaScript 迁到 TypeScript。
我是谁?一个坐标成都的前端工程师,日常用 VSCode 写代码,插件装得比头发还多(虽然发际线也在努力追赶)。最近沉迷 Rust,觉得所有权和类型系统简直太香了——所以当我看到团队里还在用裸奔的 JS 搞大型项目时,真的坐不住了。尤其在 Cursor 成了我的“AI编程搭子”之后,写 TS 简直如虎添翼,现在我已经完全离不开它了,连写个 for 循环都要喊它帮忙检查类型。
今天这篇不是什么高深教程,就是想带刚接触 TS 的朋友 30 分钟快速上手,少走我踩过的坑。毕竟,谁也不想在双11大促前夜,因为一个 undefined 把整个购物车搞崩了吧?
为啥要从 JavaScript 转 TypeScript?
先说人话:JS 是动态语言,太“自由”了。自由到你调用一个函数,根本不知道它会不会返回 null、undefined,还是直接抛个错误。本地跑得好好的,一上线就炸,运维兄弟半夜打电话骂你,测试妹子翻白眼翻到后脑勺……
而 TypeScript 是 JS 的超集,加了 静态类型系统。简单理解:你在写代码的时候,TS 就能告诉你“兄弟,这个变量可能是 undefined,你得处理一下”,而不是等到用户点击按钮才报错。
而且!TypeScript 完全兼容现有 JS 代码。你可以先把 .js 文件改成 .ts,一行代码不改,照样跑。然后慢慢加类型,渐进式升级,老板看了都说稳。
📌 真实场景:我们项目之前有个
getUserInfo()函数,有时候返回{ name: string },有时候网络失败直接返回null。结果某次新来的实习生没判空,直接user.name.toUpperCase()—— 线上事故 +1。自从迁移到 TS,这种低级错误直接被编辑器红波浪线拦住,再也不用背锅了。
30分钟实操:从零搭建一个 TS 项目
别慌,不用配置 webpack 那些祖传配置(除非你想自虐)。现在有 vite,三行命令搞定。
npm create vite@latest my-ts-app -- --template react-ts
cd my-ts-app
npm install && npm run dev
💡 如果你用的是 Vue,把
react-ts换成vue-ts就行。Vite 对 TS 原生支持,开箱即用,感动到流泪。
打开 src/main.tsx(React)或 src/main.ts(Vue),你会发现已经有类型声明了:
// React 示例
const App = () => {
const [count, setCount] = useState<number>(0); // ← 看!number 类型
return <div>{count}</d>;
}
这里 useState<number> 就是 TS 的泛型用法,明确告诉编辑器:count 只能是数字。如果你不小心写了 setCount("hello"),VSCode 马上给你标红,Cursor 甚至会弹出提示:“Hey bro, this should be a number!”
核心概念速通:类型、接口、泛型
1. 基础类型(Primitive Types)
TS 的基础类型和 JS 差不多,但多了 any、unknown、never 这些“哲学家”。
| JS 类型 | TS 类型 | 说明 |
|---|---|---|
string |
string |
字符串 |
number |
number |
数字(不分 int/float) |
boolean |
boolean |
布尔值 |
null |
null |
空值 |
undefined |
undefined |
未定义 |
| 任意类型 | any |
⚠️ 别用!等于关掉 TS |
| 安全的任意 | unknown |
✅ 推荐,需类型断言才能用 |
🙅♂️ 血泪教训:刚学 TS 时为了快,到处写
any,结果类型检查形同虚设。后来被 Cursor 一顿教育:“You’re wasting TypeScript!” 才改邪归正。
2. 接口(Interface) vs 类型别名(Type Alias)
用来描述对象结构。比如用户信息:
// 方式1:interface
interface User {
id: number;
name: string;
email?: string; // ? 表示可选
}
// 方式2:type alias
type User = {
id: number;
name: string;
email?: string;
};
区别在哪?
interface可以合并(适合做插件扩展)type更灵活,能表示联合类型(string | number)、元组等
日常开发中,我基本都用 interface,除非需要高级类型操作。
3. 泛型(Generics):让代码更“通用”
假设你要写一个获取数据的函数:
function fetchData<T>(url: string): Promise<T> {
return fetch(url).then(res => res.json());
}
// 使用时指定类型
const user = await fetchData<User>('/api/user');
// 现在 user 自动有 id/name/email 提示!
泛型就像“占位符”,用的时候再填具体类型。配合 VSCode 的智能提示,写 API 调用再也不用去翻 Swagger 文档了。
实战:改造一个 JS 函数为 TS
来看一个经典场景:处理表单提交。
原来的 JS 代码(危险!):
function handleSubmit(data) {
console.log(data.username.toUpperCase()); // 如果 username 是 null?boom!
}
TS 改造后:
interface FormData {
username: string;
age?: number; // 年龄可选
}
function handleSubmit(data: FormData) {
// TS 确保 username 一定是 string,不会是 null/undefined
console.log(data.username.toUpperCase());
// 如果要用可选属性,得先判断
if (data.age !== undefined) {
console.log(`年龄: ${data.age}`);
}
}
现在,只要你调用 handleSubmit({}),编辑器立刻报错:“Property 'username' is missing”。再也不怕前端传参漏字段了!
和 GitHub 协作:TS 让 PR 更清爽
我们团队有个规矩:没有类型定义的 PR 直接打回。为什么?因为 TS 能极大减少 code review 的沟通成本。
想象一下:你提交一个工具函数 formatDate(date),Reviewer 不用猜 date 是 string 还是 Date 对象,也不用担心返回值是不是 null。所有契约都在类型里写清楚了。
而且,GitHub 的 PR diff 里,TS 类型变更一目了然。比如你把 User.name 从 string 改成 string | null,Reviewer 马上意识到:“哦,这个字段可能为空,调用方得改”。
🤝 团队小故事:上个月,后端改了 API,把
avatar字段从必填变成可选。以前 JS 项目得靠人工通知+全局搜索,现在 TS 直接报错,谁调用了就谁改,效率翻倍。
调试技巧 & 开发体验
1. VSCode + TS = 黄金搭档
装好官方 TypeScript and JavaScript Language Features 插件(其实默认就有),享受:
- 自动类型推导
- 重命名符号(F2 全局改)
- 跳转到定义(Ctrl+Click)
- 错误实时高亮
配合 Cursor,写 TS 简直爽飞。比如输入 // 创建一个用户列表的函数,它能自动生成带类型的函数骨架,还能根据上下文推断参数结构。
2. 处理第三方库: DefinitelyTyped
很多老库没有 TS 支持?别怕,社区有 DefinitelyTyped 项目(GitHub 上超 50k stars)。
安装类型定义:
npm install --save-dev @types/lodash
然后就能享受 lodash 的完整类型提示了!
3. 渐进式迁移策略
别想着一口吃成胖子。我们的做法:
- 先把新文件用
.ts后缀 - 旧
.js文件加// @ts-check注释,开启局部类型检查 - 逐步替换
any为具体类型 - 最终删除所有
@ts-ignore
性能 & 浏览器兼容性?
放心!TS 只在开发阶段生效,编译后就是纯 JS,0 运行时开销。通过 tsconfig.json 配置 target(比如 ES2015),还能自动转译语法,兼容老旧浏览器。
{
"compilerOptions": {
"target": "ES2015",
"module": "ESNext",
"strict": true,
"jsx": "react-jsx"
}
}
strict: true 强烈建议开启!虽然一开始报错多到想砸键盘,但长期看,它能帮你避开 80% 的运行时错误。
写在最后:TS 不是银弹,但值得拥有
学 TS 的契机?其实是被领导逼的(笑)。他说:“咱们要做技术债清理,TS 是第一步。” 结果真香了——现在写代码像在玩解谜游戏,TS 编译器就是那个不断给你线索的 NPC。
30 分钟当然不能精通 TS,但足够让你:
✅ 理解核心概念
✅ 搭建项目
✅ 写带类型的函数和组件
✅ 避开常见坑
最重要的是:你的代码从此有了“文档”。类型就是最好的注释。
下次当你看到同事在群里哀嚎 “xxx is not a function”,你可以微微一笑,默默 push 你的 .ts 文件,然后去楼下茶馆点杯竹叶青——毕竟,成都的节奏,就是这么舒服 😎。
附:快速自查清单
- 项目已用 Vite + TS 模板初始化
-
tsconfig.json开启了strict - 所有函数参数都有类型标注
- 没有滥用
any - 第三方库安装了
@types/xxx - GitHub PR 包含类型变更说明
搞定这些,恭喜你,已经超越了 70% 的前端团队!剩下的 30%,让他们继续在 undefined 的海洋里游泳吧 🏊♂️

评论 0