TypeScript快速入门:30分钟上手指南
上周五晚上十点半,实验室的空调还在嗡嗡作响,我盯着屏幕上那行红色的 Cannot find module 'xxx' or its corresponding type declarations 报错,一边啃着外卖冷掉的冒菜,一边在心里默默问候产品经理祖宗十八代。事情是这样的:我们组正在做一个给本地社区团购平台做的后台管理系统,原本用的纯 JavaScript + Vue 2,结果老板突然说要“提升代码质量,拥抱现代前端工程化”,硬是要我们在下个版本切换到 TypeScript。
“提升简历含金量嘛”,老板拍着我肩膀笑得像只老狐狸,“你看人家大厂 JD 都写着‘熟练掌握 TypeScript’,你研二了,不得抓紧?”
行吧,为了简历上能多一行“TypeScript 项目经验”,也为了不被 GitHub 上那些 Star 几万的开源项目甩得太远,我咬咬牙,决定速成一波。毕竟咱们成都人讲究“巴适得板”,但 deadline 面前,谁还顾得上喝茶打麻将?
为什么非得学 TypeScript?——来自一个被 Bug 教育过的研狗
其实早在去年双11搞一个电商运营看板项目时,我就被 JavaScript 的“灵活性”狠狠教育过一次。当时写了个商品库存计算函数,传参时手滑把字符串 "100" 当成了数字 100 传进去,结果库存显示负数,运营小姐姐直接冲到我们工位:“你们这系统是不是想让我背锅?”
更离谱的是,本地测试一切正常,上线后因为某些异步加载顺序问题,某个对象属性是 undefined,页面直接白屏。运维大哥半夜打电话过来:“兄弟,线上挂了,用户进不去,快看看!” 那一刻我真的想砸电脑。
而 TypeScript,说白了就是给 JavaScript 加了一层“类型保险”。它不会阻止你写出逻辑错误,但至少能让你在写代码的时候就发现“哎,这个变量明明是 string,你怎么当 number 用了?” 这种低级错误。对于像我这种经常边写代码边刷 B 站的人,简直是救命稻草。
而且现在主流框架(React、Vue 3、Angular)都原生支持 TS,GitHub 上 Top 10k 的前端项目,90% 以上都用上了。你要是连 interface 和 type 都分不清,简历投出去怕是要石沉大海。
环境搭建:别被配置劝退!
很多人一听到“编译”“配置”就头大,觉得 TS 比 JS 复杂多了。其实真没那么可怕!我拿我们实验室的项目举例,从零开始搭一个 TS 环境,10 分钟搞定。
首先,确保你装了 Node.js(建议 16+),然后初始化项目:
mkdir ts-quick-start && cd ts-quick-start
npm init -y
接着装 TypeScript 本体和开发依赖:
npm install --save-dev typescript @types/node
注意那个 @types/node,这是 TS 的“类型定义包”。很多 npm 包本身是用 JS 写的,TS 不认识它们的结构,就需要这些 @types/xxx 包来告诉 TS:“嘿,这个模块长这样”。
然后生成默认配置文件 tsconfig.json:
npx tsc --init
打开 tsconfig.json,你会看到一堆注释掉的选项。对我们新手来说,先改几个关键的就行:
{
"compilerOptions": {
"target": "ES2020", // 编译成什么 JS 版本
"module": "commonjs", // 模块系统
"outDir": "./dist", // 输出目录
"rootDir": "./src", // 源码目录
"strict": true, // 开启严格模式(强烈建议!)
"esModuleInterop": true, // 兼容 CommonJS 和 ES Module
"skipLibCheck": true, // 跳过类型定义文件检查(避免第三方库报错)
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"] // 包含哪些文件
}
重点来了:一定要开 strict: true!虽然一开始会报一堆错,但它能逼你写出更健壮的代码。我们组有个师兄就是因为没开 strict,结果漏判了一个可能为 null 的字段,导致整个订单流程崩了,被测试追着骂了三天。
最后建个 src/index.ts,写点 Hello World:
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("成都研狗"));
运行编译:
npx tsc
你会发现 dist/index.js 生成了,内容就是普通的 JS。直接跑:
node dist/index.js
// 输出:Hello, 成都研狗!
搞定!是不是比想象中简单?如果你用 VS Code(推荐!),装个官方 TypeScript 插件,还能实时看到类型提示和错误,体验飞起。
核心概念:interface、type、泛型,到底有啥区别?
接下来才是重头戏。TS 最核心的就是类型系统。别被术语吓到,我用人话给你解释。
1. 类型注解(Type Annotations)
最基础的,就是给变量、函数参数、返回值加类型:
let age: number = 24;
let isStudent: boolean = true;
let hobbies: string[] = ["coding", "eating hotpot"];
function add(a: number, b: number): number {
return a + b;
}
注意:TS 是“静态类型”,意思是类型检查发生在编译时,运行时还是纯 JS。所以你不用担心性能问题——根本没额外开销!
2. interface vs type
这是新手最容易懵的地方。简单说:
- interface 主要用来描述“对象的形状”(shape),比如 API 返回的数据结构。
- type 更灵活,可以是原始类型、联合类型、元组,甚至 interface 的组合。
举个我们项目里的真实例子。运营后台要展示商家信息,接口返回大概是这样:
{
"id": 123,
"name": "春熙路冒菜王",
"contact": "138xxxx1234",
"isActive": true
}
用 interface 定义:
interface Merchant {
id: number;
name: string;
contact: string;
isActive: boolean;
}
但如果某个字段可能是字符串也可能是数字(比如旧系统遗留问题),就得用联合类型:
type Contact = string | number;
interface Merchant {
id: number;
name: string;
contact: Contact; // 看,这里用了 type
isActive: boolean;
}
另外,interface 支持“合并”(declaration merging),这在扩展第三方库类型时特别有用。比如你想给 Axios 的 response 加个自定义字段:
// 声明合并
declare module 'axios' {
interface AxiosResponse<T = any> {
config: any;
duration?: number; // 我们加的字段
}
}
而 type 就不行。所以一般建议:优先用 interface 描述对象,用 type 做复杂类型组合。
3. 泛型(Generics)——让函数更“通用”
泛型听起来高大上,其实就是“把类型当作参数传进去”。比如我们写个数组工具函数:
// 不用泛型:只能处理 number
function getFirst(arr: number[]): number | undefined {
return arr[0];
}
// 用泛型:可以处理任何类型!
function getFirst<T>(arr: T[]): T | undefined {
return arr[0];
}
// 使用
const numbers = [1, 2, 3];
const firstNum = getFirst(numbers); // TS 自动推断 T 为 number
const merchants: Merchant[] = [...];
const firstMerchant = getFirst(merchants); // T 推断为 Merchant
在 Vue 3 或 React 里,泛型更是无处不在。比如定义一个可复用的表格组件,列配置就需要泛型:
interface Column<T> {
key: keyof T; // 只能是 T 对象的 key
title: string;
}
// 这样就能保证 column.key 一定是 merchant 的某个属性
const columns: Column<Merchant>[] = [
{ key: "name", title: "商家名称" },
{ key: "contact", title: "联系方式" }
];
是不是瞬间感觉代码安全多了?
实战:把现有 JS 项目迁移到 TS
光说不练假把式。我们实验室那个运营后台,原本是 Vue 2 + JS,怎么平滑迁移到 TS?
步骤 1:渐进式迁移
别想着一口吃成胖子。TS 支持 .js 和 .ts 文件混用!我们先把入口文件改成 .ts,其他慢慢改。
- main.js
+ main.ts
然后安装 Vue 的类型定义:
npm install --save-dev @types/vue
步骤 2:处理第三方库
比如我们用了 moment.js 处理时间,但 TS 不认识它。这时候:
npm install --save-dev @types/moment
如果某个库没有 @types/xxx 怎么办?比如我们用了一个小众的图表库。那就自己写个声明文件 shims.d.ts:
// src/shims.d.ts
declare module 'awesome-chart-lib' {
export function renderChart(el: HTMLElement, data: any): void;
}
TS 就不会再报错了。
步骤 3:处理动态属性和 any
最头疼的是那些“不确定类型”的地方。比如从后端拿的数据,可能某些字段不存在。这时候别偷懒写 any!用 unknown + 类型守卫更安全:
// bad
const data: any = await fetch('/api/merchants');
// good
interface ApiResponse {
code: number;
data: Merchant[];
}
const res = await fetch('/api/merchants');
const json: unknown = await res.json();
// 类型守卫:确保 json 符合预期结构
if (isApiResponse(json)) {
console.log(json.data[0].name);
}
function isApiResponse(obj: unknown): obj is ApiResponse {
return (
typeof obj === 'object' &&
obj !== null &&
'code' in obj &&
'data' in obj
);
}
虽然代码多了几行,但换来的是运行时的安全。想想上次因为字段缺失导致的白屏事故,这点工作量算啥?
调试技巧 & 工具链
VS Code 必装插件
- TypeScript Hero:自动导入、整理 import
- Error Lens:直接在代码行内显示错误(不用 hover)
- Bracket Pair Colorizer:括号配色(写 JSX/TSX 时救命)
调试 TS 代码
直接在 VS Code 里按 F5,选 Node.js 环境,它会自动生成 launch.json。设置断点后,不仅能看变量值,还能看到类型信息!比如鼠标 hover 一个变量,会显示 string | undefined,这对排查逻辑分支超有用。
浏览器兼容性?
放心,TS 编译后的 JS 兼容性由 tsconfig.json 里的 target 决定。比如设成 ES5,就能跑在 IE 11(虽然没人用了吧)。我们项目 target 是 ES2020,配合 Babel 转换,完美支持现代浏览器。
性能优化小贴士
- 开发时用
tsc --watch监听文件变化,自动编译 - 生产构建交给 Webpack/Vite,它们有更高效的 TS loader(比如
esbuild-loader) - 别在循环里做复杂类型推断,会影响编译速度(不过对 99% 的项目没影响)
30分钟后,我的收获
折腾完这一套,我不仅把实验室项目成功迁移到 TS,还顺手给 GitHub 个人主页加了个新项目:vue-ts-admin(名字瞎编的)。虽然 star 数还是个位数,但至少简历上能写“主导前端技术栈升级,引入 TypeScript 提升代码健壮性,减少线上 Bug 40%”(数据是我瞎编的,但老板信了)。
更重要的是,现在写代码时那种“提心吊胆”的感觉没了。以前每次改完都要手动点遍所有页面,生怕哪里报错;现在只要 VS Code 不飘红,基本就稳了。上周产品又提了个新需求,说要在商家列表加个“是否支持配送”的筛选,我十分钟写完,类型检查全过,提交 PR 时底气十足。
当然,TS 也不是银弹。它不能防止你写出烂算法,也不能代替单元测试。但对于咱们这些既要赶 deadline 又想保住头发的研究生来说,它绝对是性价比最高的“防坑工具”。
所以,别再犹豫了。花 30 分钟,照着本文走一遍。等你下次在面试时自信地说出“我们项目全面使用 TypeScript,配合 ESLint + Prettier 保证代码规范”,HR 眼里绝对会放光。
毕竟,在成都这座慢节奏的城市里,我们写代码可以追求“巴适”,但交付质量,必须“雄起”!
P.S. 如果你在迁移过程中遇到 Cannot find name 'require' 这种报错,大概率是 tsconfig.json 没配好模块系统,记得检查 module 和 moduleResolution。别问我是怎么知道的,问就是凌晨三点的泪 😭

评论 0