《TypeScript编程入门》前言

《TypeScript编程入门》前言:说明本书的目标读者与前置知识、五部分 18 章的结构分工、每节的组织方式、代码约定与 TypeScript 5.x 版本基线,并给出顺序通读、按需跳读、当参考手册用三种阅读路径的建议,附各部分的阅读时长估算。

关于这本书

这是一本写给「想真正学会 TypeScript」的人的书,而不是一本写给「想在面试前背几个概念」的人的书。全书共 18 章 54 节,另加序、前言、目录三篇前置内容与四篇附录,合计 61 篇。它假定你愿意动手写代码、愿意在报错里泡一会儿、愿意花时间想清楚「为什么这样设计」,而不是只想知道「这样写能不能过」。

在正文开始之前,这一篇把体例讲清楚:这本书写给谁、怎么组织、代码按什么约定写、不同的人应该怎么读。读完它,你就能判断该从哪一页开始,以及哪些部分可以放心跳过。

目标读者与前置知识

最低前置知识:能读懂基本的 JavaScript 代码。具体来说,你应当熟悉以下内容:

  • 变量声明(let / const)、基本运算符、条件与循环;
  • 函数声明与箭头函数、参数与返回值的概念;
  • 数组与对象的常用操作(map / filter / reduce、解构、展开);
  • this 的基本行为、原型链的直觉印象;
  • 模块(import / export)与 Promise、async / await 的基本用法。

如果你完全不会 JavaScript,建议先花一到两周补上基础再回到这本书。原因不是本书的示例有多难,而是 TypeScript 的每一个特性都建立在 JavaScript 的语义之上——不理解「函数是一等公民」「对象是按引用传递」,就很难理解为什么类型要那样设计。补基础时不必追求深入,能把上面列出的内容用起来就够了。

如果你有其他静态类型语言的经验(Java、C#、Rust、Go、Swift 等),你可以直接开始,但要特别留意本书反复强调的三处差异:TypeScript 采用结构化类型系统(看形状,不看名字);类型在编译后被完全擦除,运行时没有类型信息;any 是一个可以随时启用的逃生舱,滥用它会让你退回到无类型的处境。

如果你是有经验的 JavaScript 开发者,前 4 章对你来说会比较轻松,重点应该放在第 5 章之后——那里才是 TypeScript 真正区别于「加注解的 JS」的地方。

全书结构:五部分 18 章

全书按学习曲线分为五个部分,每一部分解决一类问题:

部分章节主题解决的问题
第一部分第 1–4 章基础与起步这门语言是什么、怎么装、怎么写第一行带类型的代码
第二部分第 5–7 章类型建模如何用类型描述业务里的对象、状态与分支
第三部分第 8–10 章类型系统进阶泛型、映射类型、条件类型,把类型当程序写
第四部分第 11–16 章运行时与工程实践模块、声明文件、校验、错误、测试与构建
第五部分第 17–18 章全栈实战项目结构、契约共享、部署与迁移

每一部分的内部也是递进的。以第二部分为例:第 5 章先建立「用 interface 与 type 描述对象形状」的基本手法,第 6 章把对象升级为类与继承,第 7 章则引入联合类型与判别联合——这是 TypeScript 建模能力的真正核心,也是很多 JavaScript 开发者第一次感受到「类型可以表达业务规则」的地方。

每一节的组织方式

为了让 54 节保持一致的节奏,每一节都按同样的四段式组织:

  1. 本节目标:开头用一小段话说明这一节要解决什么问题、读完之后你能做什么。你可以用它快速判断这节是否是你现在需要的。
  2. 正文小节:主体内容,通常包含 3 到 6 个 ### 小节。每个小节聚焦一个具体问题,尽量给出可运行的代码与编译器反馈。
  3. 小结:末尾用几句话收束,点明这一节最值得记住的判断标准,而不是复述正文。
  4. 衔接下一节:最后一句通常指向下一节,说明接下来要解决的问题与本节的关系,方便你判断是否可以跳过。

这种结构的代价是每节都有一些重复的仪式感,好处是你随时可以抽出一节独立阅读,而不必担心缺少上下文。当作参考手册用时,这一点会尤其方便。

代码约定

为了让你复制出来的代码能直接跑,本书在代码上有几条统一约定:

  • 语言基线:以 TypeScript 5.x 为准。5.x 之后引入的 const 类型参数、satisfies 操作符等特性,会在相关章节标注适用版本。
  • 严格模式:所有示例默认运行在 strict: true 下。这意味着 strictNullChecks、noImplicitAny 等选项全部开启。如果你在自己的项目里没开严格模式,某些示例的报错可能不会出现——本书强烈建议你开启它。
  • 运行环境:默认使用 Node.js 20 以上版本,示例以 ES 模块("type": "module")为主。涉及浏览器环境的章节会明确说明。
  • 代码块标注:所有代码块都标注了语言,ts 表示 TypeScript,js 表示 JavaScript,json 表示配置,bash 表示命令行。
  • 省略与完整性:为了聚焦重点,个别示例会省略与主题无关的部分,此时会以注释标明。除标注外,示例都可以直接运行。

下面是一个符合上述约定的最小示例,你可以用它验证自己的环境是否配置正确:

// hello.ts —— 在 strict 模式下编译
interface Greeting {
  name: string;
  times?: number;
}

function greet({ name, times = 1 }: Greeting): string {
  return `Hello, ${name}!`.repeat(times);
}

console.log(greet({ name: "TypeScript", times: 2 }));

把它保存为 hello.ts,用 npx tsc hello.ts 编译或 npx tsx hello.ts 直接运行,如果输出两行 Hello, TypeScript!,说明环境没问题。

反复出现的几个术语

为了避免读到后面产生歧义,这里先约定几个在全书反复出现的关键词。它们不是严格的规范定义,而是本书的行文口径:

术语本书中的含义
类型注解写在变量、参数、返回值后面的 : T 形式的标注,是「声明」而非「断言」
类型推断编译器根据上下文自动得出类型的过程,是 TypeScript 好用的一半原因
类型擦除编译产物中不保留任何类型信息,这是理解「运行时盲区」的前提
结构化类型只要形状匹配即可互相赋值,不看类型的名字与来源
判别联合用一个字面量字段区分若干变体的联合类型,是建模状态机的首选手法
类型收窄编译器根据控制流判断某个变量在当前位置更精确的类型
工具类型由 TypeScript 内置的、对类型做变换的类型函数,如 Partial、Pick

如果某个术语在正文里第一次出现时你还不熟悉,不必停下来死磕,往后读一两节再回头看这张表,往往会豁然开朗。类型系统的概念天然是互相定义的,强行逐个击破反而低效。

学习时间估算

为了让「按需跳读」这条路径可执行,这里给出一份粗略的时间参考(按每天投入一小时计):

  • 第 1–4 章(基础与起步):约 1 周。内容不深,但环境配置需要一点试错时间。
  • 第 5–7 章(类型建模):约 2 周。这是全书最重要的部分,建议放慢速度。
  • 第 8–10 章(类型系统进阶):约 2 至 3 周。泛型与条件类型需要反复练习。
  • 第 11–16 章(运行时与工程实践):约 2 至 3 周。可以结合手上的项目同步实践。
  • 第 17–18 章(全栈实战):约 1 周。更适合在有真实项目时精读。

总计约 8 到 10 周可以完成一遍系统学习。如果你的目标是「两周内能上手写业务代码」,那么集中读第 3、4、5、7、11、13 章这六章,跳过类型进阶与工程化部分,也能获得一个可用的起点——只是后面遇到复杂类型时仍需要回来补课。

三种阅读路径

同一本书,不同的人有不同的用法。下面给出三种典型路径,你可以按自己的目标选择。

路径一:顺序通读。 适合零基础或想系统重建知识结构的人。从第 1 章开始按顺序读,每节都动手写代码,遇到不懂的不要跳过,标记下来继续读,读完一整章后回头解决标记的问题。预计需要 6 到 10 周。这条路径的收益最完整,但需要耐心。

路径二:按需跳读。 适合已有 JavaScript 经验、只想补齐类型短板的人。可以跳过第 1 章到第 4 章,直接从第 5 章读起;如果工作中已经在用泛型,可以再跳过第 8 章的前两节,从 8.3 开始。第四部分的第 13 章(运行时校验)和第 15 章(测试)值得单独抽时间读,它们解决的问题与语法无关,但对工程质量影响很大。

路径三:当参考手册用。 适合已经会用 TypeScript、需要查具体写法的人。这种情况下不必按顺序读,直接看目录定位到相关章节,利用每节的「本节目标」和「小结」快速确认是否命中需求。附录 A 的语法速查表和附录 B 的工具类型清单是为这种用法准备的,可以先从它们入手。

无论选哪条路径,都建议至少完整地动手跑通第 2 章的示例。环境配置是所有后续内容的地基,地基不稳,后面每一步都会变得别扭。

一点阅读提醒

最后有三条提醒,它们能显著影响你的阅读体验:

不要用 any 逃避报错。 初学阶段最容易养成、也最难戒掉的习惯,是一遇到看不懂的类型错误就加个 any 让它闭嘴。这会让你在短期内顺畅,长期内一无所获。遇到报错时,先读懂它想说什么,实在想不通再来查书。

不要追求一次看懂所有细节。 类型系统里有很多「先记住结论、以后再理解原因」的地方。第一遍读不懂某个推导过程,可以先接受结论继续往下,等到用到了再回来。纠结于一个角落,会让你卡在第一周。

不要只读不写。 这本书的示例都很短,正是为了让你能随手敲一遍。只读不写,你收获的会是「我好像懂了」的错觉;敲过一遍、报过错、改对过,才是真的懂了。

关于怎么判断自己真的学会了

学完一章之后,怎么知道自己是真懂了还是「读懂了」?这个问题比它看起来更重要,因为类型系统特别容易制造「我明白了」的错觉——看着别人写好的类型推导,每一步都合理,合上书却写不出来。

下面这份清单可以用来自查。每一项都对应一种可以被观察的行为,而不是一种感觉。如果你能不打草稿地做到,说明这部分知识已经变成了你的能力:

  • 看到一个新的数据结构,先写类型再写实现。 而不是先写完逻辑,再回头补一堆 any。
  • 能预判一段代码会不会报错。 在按下保存键之前,你心里已经知道编译器会说什么。
  • 能读懂报错的意图,而不是它的字面。 看到 Type 'X' is not assignable to type 'Y',你能说出这两个类型在哪个字段上不兼容。
  • 知道什么时候不该用类型。 能判断某个地方写类型是收益,还是纯粹的噪音。
  • 能读懂第三方库的类型定义。 打开一个流行库的 .d.ts,你能大致跟上它的类型设计思路。
  • 能处理运行时数据。 看到一个来自接口的 unknown,你知道该在哪里把它变成可信的类型。
  • 能用类型表达业务规则。 像「已支付的订单不能再次支付」这种约束,你知道它可以被编码进类型里,而不是只写在注释中。
  • 能解释自己为什么这样写。 面对「为什么这里用泛型而不是重载」,你给得出理由,而不是「书上是这么写的」。
  • 能判断类型管到哪为止。 知道哪些地方可以放心交给编译器,哪些地方必须由运行时校验兜底。

反过来,下面这些信号说明你可能还停在「读过」的阶段:一遇到类型报错就想加 any;能看懂书里的例子但自己写不出来;觉得类型注解是一种不得不写的仪式;分不清「类型检查通过」和「程序正确」的区别。

还有一个更隐蔽的信号:你写的类型只在编译期存在,从没影响过你的设计决策。如果类型只是写完逻辑之后补上去的装饰,那它就还没有真正进入你的工作方式。

如果你发现自己中了几条,不必沮丧。类型能力本来就是靠「写—错—改」的循环长出来的,回到对应章节,把示例亲手敲一遍,往往比再读一遍有效。真正的分水岭不在「知道有这个特性」,而在「遇到问题时能想起它」。

这张清单也可以反过来用:每读完一个部分,回来对照一次,看看能打勾的条目有没有变多。它比「读完了几章」更能说明你的进度。

关于练习与验证

这本书没有独立的习题册,但每一节的示例本身就是练习。推荐的做法是:先看问题描述,自己尝试写一遍,再看书里的写法。类型系统的学习高度依赖「预判—验证」的循环——你先在脑子里推断某个写法会不会报错、报什么错,然后让编译器告诉你答案。这个循环跑得越多,你对类型的直觉就越准。

如果你在某个示例上卡住了,最有效的办法往往不是重读正文,而是故意把代码改坏,看看编译器会报什么。错误信息本身携带了大量信息:它告诉你哪个类型不兼容、为什么不兼容、期望的是什么。学会读类型报错,是这本书希望帮你建立的一项独立能力。

关于版本演进与长期有效性

TypeScript 保持着相当稳定的发布节奏,大约每三个月一个次版本。这意味着任何一本纸面上的技术书,都难免在某些细节上落后于最新版本。本书的应对方式是:把版本相关的内容集中标注,把与版本无关的原则重点讲透。

具体来说,凡是依赖特定版本特性的写法,都会在正文里注明适用的版本区间,例如「satisfies 操作符需要 TypeScript 4.9 及以上」。如果你的环境版本较低,编译器会直接告诉你某个语法不认识,这时按标注升版本或换写法即可。而那些真正构成你判断力的内容——为什么用联合类型而不是布尔标志位、什么时候该把类型抽成泛型、编译期与运行期的职责边界在哪——这些不会因为版本更迭而失效。

这也是本书不把「最新特性清单」当作卖点的原因。追新很容易,理解原理很难,而后者才是能陪你走更远的东西。当你读到一个看似过时的写法时,不妨多想一步:它当年要解决什么问题?这个问题今天解决了吗?如果答案是「解决了,只是换了形式」,那你就真正读懂了这一节。

关于配套资源

本书不附带独立的代码仓库,原因很简单:示例足够短,短到你直接复制进编辑器就能用。与其维护一份可能随时间腐坏的仓库,不如让每一段代码都保持「自包含、可复制、可运行」的状态。

真正值得你准备的配套环境只有两样:一个装好 Node.js 20 以上版本的本机环境,以及一个带 TypeScript 支持的编辑器。本书推荐使用 VS Code,因为它内置了 TypeScript 的语言服务,能实时给出与编译器一致的类型提示和报错——这对理解类型推断的过程帮助极大。如果你用别的编辑器,只要它接入了 TypeScript 语言服务,体验也是一样的。

附录部分承担了「速查」的角色:附录 A 汇总语法,附录 B 汇总内置工具类型,附录 C 汇总常用工具与库,附录 D 汇总常见问题。它们不按教学顺序组织,而是按查阅顺序组织,适合在你写代码卡住时随手翻。建议在第一次通读时先跳过附录,等到有具体问题再回来。

勘误与反馈

技术书难免有疏漏,尤其是涉及版本演进的细节。如果你在阅读中发现示例无法运行、表述有歧义,或者某个知识点讲得不够清楚,欢迎在站点相应页面留言指出。对于确认的问题,我会在后续修订中更新正文,并在页面的更新说明里标注。

需要说明的是,本书面向的是「长期有效的判断力」,而不是「某个月份的 API 清单」。生态在快速变化,具体的库名、配置项、默认行为都可能过时;但类型设计的原则、编译期与运行期的分工、结构化的取舍方式,这些内容的保质期要长得多。如果某一天你发现书里的某个工具已经被取代,但其中的思路仍然有用,那这本书就达到了它想要的效果。

现在,让我们从第 1 章开始。

先回答那个最朴素的问题:TypeScript 到底是怎么来的,它想解决什么。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「typescript」更多文章

  1. 《TypeScript高级编程》11.3 类型驱动架构与团队规范
  2. 《TypeScript高级编程》11.2 渐进式迁移与严格化路径
  3. 《TypeScript高级编程》11.1 TS 版本演进与 breaking changes