TypeScript快速入门:30分钟上手指南

朱浩然♪
2025-12-17 08:22
阅读 651

上周五晚上十点半,实验室的空调还在嗡嗡作响,我盯着屏幕上那行红色的 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 没配好模块系统,记得检查 modulemoduleResolution。别问我是怎么知道的,问就是凌晨三点的泪 😭

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝