本节目标:回答「我该在什么项目里用 TypeScript」这个非常实际的问题,并让你对它的生态版图有一个整体印象——知道有哪些主战场、有哪些关键工具、它们各自负责什么。读完本节,你就能为自己的下一个项目做出有依据的选型判断,而不是因为「别人都在用」而跟风。
1.3 适用场景与生态版图
前两节讲了 TypeScript 是什么、它和 JavaScript 什么关系。这一节换个角度:它在真实世界里被用在哪里,以及你什么时候该用它。
1.3.1 判断标准:收益随什么增长
TypeScript 的收益不是恒定的,它随下面几个变量增长:
| 变量 | 为什么影响收益 |
|---|---|
| 代码规模 | 人脑记不住几十个模块的接口,类型是外部记忆 |
| 人数与协作强度 | 类型是「可执行的接口文档」,减少口头约定 |
| 生命周期 | 维护期越长,早期投入的类型成本越摊薄 |
| 重构频率 | 改一个接口,编译器列出所有需要跟着改的地方 |
| 数据边界复杂度 | API、配置文件、第三方返回值越多,越需要契约 |
反过来,如果是「一次性的 50 行脚本」「周末做完就丢的原型」,类型带来的收益可能低于成本。这不是 TypeScript 的缺陷,而是所有静态类型语言的共性。
一个粗略的经验法则:
- 单人、脚本、一次性 → 用 JavaScript 更省事
- 多人、长期、有接口 → 用 TypeScript,几乎总是划算
- 中间地带 → 用
.ts写核心逻辑,.js写胶水,通过allowJs混合
1.3.2 不太适合的场景
诚实地说,有几类场景 TypeScript 帮不上太多忙,或者反而添乱:
- 只做运行时校验的场景:类型在运行时不存在,如果你的核心需求是「校验外部数据」,需要的是 Zod 这类运行时方案 ,而不是类型注解本身。
- 性能极端敏感的启动路径:类型检查与转译要花时间,冷启动受限的场景要考虑构建产物与增量编译。
- 团队完全零基础且拒绝学习成本:强推类型会引发抵触,此时渐进式迁移(第 18 章)比「一刀切」更现实。
1.3.3 前端框架生态
前端是 TypeScript 最成熟的主战场。三大框架都提供一流支持:
React —— 函数组件与 Hooks 的类型几乎可以完全推断:
type Props = {
title: string;
count?: number;
onSelect: (id: string) => void;
};
export function Card({ title, count = 0, onSelect }: Props) {
return (
<button onClick={() => onSelect(title)}>
{title} × {count}
</button>
);
}
count 因为有默认值,调用方可以不传;onSelect 的签名一旦写错,编译器立刻报错。完整的工程化实践可以延伸阅读 React + TypeScript 实战指南
。
Vue —— <script setup lang="ts"> 与 defineProps 宏让类型与模板联动:
<script setup lang="ts">
interface Props {
items: string[];
selected?: string;
}
const props = defineProps<Props>();
const emit = defineEmits<{ (e: 'pick', value: string): void }>();
</script>
Angular —— 从诞生起就把 TypeScript 作为唯一官方语言,DI、装饰器、模板类型检查都依赖它。
三个框架的共同点:类型不只是给编辑器看的,还被模板/JSX 的类型检查利用,因此收益比纯逻辑代码更大。
1.3.4 Node.js 与后端
后端是 TypeScript 增长最快的领域。几条主流路线:
| 路线 | 代表 | 特点 |
|---|---|---|
| 全栈类型安全框架 | NestJS | 装饰器 + DI,企业级分层,见 NestJS 实战 |
| 端到端类型推导 RPC | tRPC | 前端直接调用后端函数,类型自动共享,见 tRPC 指南 |
| 轻量 Web 框架 | Express / Fastify / Hono | 按需加类型,迁移成本低 |
| ORM | Prisma / Drizzle | 从数据库 Schema 生成类型,见 ORM 数据访问 |
一个典型的 Express + TypeScript 路由:
import express, { type Request, type Response } from 'express';
interface CreateUserBody {
name: string;
email: string;
}
const app = express();
app.use(express.json());
app.post('/users', (req: Request<{}, {}, CreateUserBody>, res: Response) => {
const { name, email } = req.body; // 类型已知
res.status(201).json({ id: crypto.randomUUID(), name, email });
});
注意 import { type Request } 这种内联类型导入写法——它是 import type 的简化形式,编译后会被擦除。后端工程的完整图景可以看 TypeScript 后端开发
与 Node.js + TypeScript 实践
。
1.3.5 工具链版图
TypeScript 生态的另一半是工具链。理解它们的分工,能避免「用 tsc 做所有事」的低效做法:
| 工具 | 角色 | 类型检查 | 转译速度 |
|---|---|---|---|
tsc | 官方编译器 | ✅ 完整 | 一般 |
| esbuild | 极速打包/转译 | ❌ 只转译 | 极快 |
| SWC | Rust 实现的转译器 | ❌ 只转译 | 极快 |
| tsup | 基于 esbuild 的库打包封装 | ❌ | 极快 |
| Vite | 开发服务器 + 构建 | 通过插件 | 极快 |
| ts-node / tsx | 直接运行 .ts | 可选 | 视实现 |
主流做法是分工:esbuild/SWC/Vite 负责快速转译,tsc --noEmit 在 CI 里单独跑完整类型检查。这样开发体验快,检查又不打折。深入原理可以读 Vite 深入剖析
与 前端 esbuild 原理
。
1.3.6 跨端与边缘运行时
TypeScript 的版图早已不限于浏览器与服务器:
- 跨端桌面:Electron 与 Tauri 的主进程/前端都常用 TS,见 桌面应用与 Vite 。
- 移动端:React Native 官方模板默认就是 TypeScript。
- 边缘运行时:Cloudflare Workers、Deno Deploy、Vercel Edge 都原生支持 TS,见 边缘运行时适配 与 Hono 边缘框架 。
- 新一代运行时:Deno 与 Bun 都能直接执行
.ts,不需要单独编译步骤,见 Bun / Deno 运行时 。
deno run --allow-net server.ts
bun run server.ts
// server.ts —— Deno / Bun 下无需编译即可运行
const handler = (req: Request): Response => new Response('ok');
Deno.serve(handler);
需要提醒的是:这些运行时的「直接运行 TS」靠的是内置转译器,同样遵循类型擦除规则——它们不做类型检查(Deno 的 deno check 除外)。所以类型检查这一步依然要在 CI 里补上。
1.3.7 其他高价值场景
| 场景 | 为什么适合 TS |
|---|---|
| CLI 工具 | 参数解析与输出格式天然是结构化数据,见 CLI 开发 |
| SDK / npm 包 | 类型声明是最好的使用文档,见 包发布 |
| 微服务 | 服务间契约显式化,见 微服务架构 |
| 测试 | 断言库与类型测试工具链成熟,见 类型安全测试 |
| 可观测性 | 日志/指标字段结构化,见 OpenTelemetry |
| 多包仓库 | Project References 让增量构建可行,见 Monorepo |
1.3.8 生态成熟度的可验证信号
判断一个技术是否「成熟」,不要听宣传,看可验证的信号。TypeScript 的几条:
npm view express types
npm view zod types
{
"name": "zod",
"types": "./index.d.ts"
}
- 自带声明:
types字段存在,或包内有.d.ts,装完即可用。 - 社区声明:包没有类型时,看
@types/<pkg>是否由 DefinitelyTyped 维护。 - 框架默认模板:新建项目的脚手架默认生成
.ts配置,说明社区已把 TS 当默认选项。 - 运行时校验生态:Zod、Valibot、ArkType 等成为标配,说明社区已经正视「类型擦除」这个根本限制。
npm ls @types/node @types/express
这些信号合起来说明一件事:TypeScript 已经不是「可选项」,而是现代 JavaScript 工程默认的起点。 你接下来要学的不是「要不要用」,而是「怎么用好」。
1.3.9 一张全景表
把本节内容压缩成一张表,方便你日后回查:
| 领域 | 主流选择 | 本书对应章节 |
|---|---|---|
| 前端框架 | React / Vue / Angular | 第 17 章 |
| 后端框架 | NestJS / Express / Hono | 第 17 章 |
| 端到端类型 | tRPC / GraphQL | 第 12、17 章 |
| 数据校验 | Zod / Valibot | 第 13 章 |
| 构建工具 | Vite / esbuild / tsup | 第 16 章 |
| 测试 | Vitest / Jest + tsd | 第 15 章 |
| 运行时 | Node.js / Deno / Bun | 第 11、16 章 |
| 包管理 | npm / pnpm + workspaces | 第 16 章 |
1.3.10 选型决策清单
落到具体项目上,可以按下面的清单走一遍。它把本节内容变成可操作的判断:
| 问题 | 如果答案是「是」 | 建议 |
|---|---|---|
| 代码会维护超过 3 个月吗? | 是 | 用 TypeScript |
| 有第二个人要读或改这段代码吗? | 是 | 用 TypeScript |
| 有外部数据要进程序吗(API、配置、文件)? | 是 | 用 TS + 运行时校验 |
| 是 50 行以内的一次性脚本吗? | 是 | 可以直接用 JavaScript |
| 团队完全没接触过类型系统吗? | 是 | 先写 .ts 但不强开 strict,渐进迁移 |
| 需要给别的项目当依赖用吗? | 是 | 用 TS 并生成 .d.ts |
把这些判断固化成工程习惯,一个新项目初始化时通常就是这几步:初始化并安装依赖、生成 tsconfig 并开启严格模式、在 package.json 里挂上常用脚本。
npm init -y
npm i -D --save-exact typescript@5.9.3 @types/node@22.20.5
npm i -D tsx vitest
npx tsc --init --strict
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc -p tsconfig.json",
"typecheck": "tsc --noEmit",
"test": "vitest run"
}
}
注意 typecheck 这一条:它把「类型检查」从构建里独立出来,让 CI 能单独把门禁卡住,而开发时的 dev 走 tsx 的快速转译。这正是 1.3.5 节说的「转译与检查分离」。
1.3.11 本书的路线图
知道版图之后,再看本书的结构会清晰很多:
| 部分 | 章节 | 你会得到什么 |
|---|---|---|
| 基础 | 第 1–3 章 | 认知、环境、类型基础 |
| 语言核心 | 第 4–8 章 | 函数、对象、类、联合、泛型 |
| 类型进阶 | 第 9–10 章 | 类型编程与工具类型 |
| 工程化 | 第 11–12 章 | 模块解析、声明文件 |
| 实战 | 第 13–15 章 | 运行时校验、异步、测试 |
| 生产 | 第 16–18 章 | 构建、架构、迁移 |
建议按顺序读,但如果你已经会写 JavaScript,可以直接从第 3 章开始,遇到不熟的概念再回查。附录 A 的语法速查表可以在练习时随时翻。
小结
- TypeScript 的收益随代码规模、协作人数、生命周期、重构频率、数据边界复杂度增长;一次性小脚本未必划算。
- 它的主战场有四块:前端框架(React/Vue/Angular)、Node.js 后端(NestJS/tRPC/Express)、工具链(Vite/esbuild/SWC/tsup 与
tsc分工)、跨端与边缘运行时(Electron、React Native、Deno、Bun、Workers)。 - 工程上的标准姿势是转译与检查分离:转译交给快速工具,完整类型检查交给
tsc --noEmit在 CI 执行。 - 判断生态成熟度看可验证信号:自带
types字段、@types覆盖、脚手架默认 TS、运行时校验库成为标配。
到这里,第 1 章就结束了。你已经知道 TypeScript 从哪来、它和 JavaScript 什么关系、以及在真实项目里被用在哪里。接下来该动手了——下一章我们从《TypeScript编程入门》2.1 安装 Node.js、TS 与编辑器配置 开始,把环境搭起来,写出第一个能跑起来的 TypeScript 程序。
阅读导航:上一节:1.2 与 JavaScript 的关系(超集·类型擦除) · 下一节:2.1 安装 Node.js、TS 与编辑器配置 。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。