Search K
Appearance
Appearance
TypeScript 是 JavaScript 的超集,它给 JS 添加了一套静态类型系统。
TS 的入门就是学怎么给 JS 添加类型,比如函数、class、构造器、对象等怎么加类型,这些其实文档写的很清楚了,网上也有很多相关资料。
TS 的进阶部分就是类型编程,也就是如何动态生成一些类型,这部分是 TS 最强大也是最复杂的部分,被戏称为 "类型体操",但是网上没有专门系统讲这部分的。所以我才写了这本小册,希望能把类型编程讲清楚,同时也讲下 TS 类型检查的实现原理以及怎么阅读 TS 源码。
首先我们明确了什么是类型安全,TypeScript 添加的静态类型系统就是为了保证类型安全的,把一些类型不兼容的错误提前到编译期间检查出来,提高代码的健壮性,这就是为什么大型项目必然会用静态类型的语言来写。
大家可能有写过 java 代码,会发现它的那套类型系统好像没有 TS 的这么复杂,所以我们又理了下类型系统的三个层次,支持泛型并且支持类型编程的类型系统是最复杂的,TS 的类型系统就是这样。
之后我们过了遍 TS 类型系统中的类型和支持的类型计算,其实大部分类型是和 JS 中的保持一致的,只不过扩展了 interface、enum、元组等复合类型,和 never、any、void 等特殊类型。
这些基础是告诉我们怎么声明类型的,而类型编程则是动态生成类型,对类型做增删改,比直接声明类型更高一层。
后面我们分别讲学了模式匹配(各种类型通过 infer 提取某部分类型)、重新构造(类型是不可变的,想修改只能重新构造一个新的。最主要的是通过映射类型来生成新的索引类型)、递归(类型编程里涉及到数量不确定的问题,要条件反射的想到用递归来解决)、数组长度计数(严格来说是元组长度,通过构造不同元素个数的元组再取长度的方式实现计数)、联合类型的分发特性(分布式条件类型,当联合类型作为类型参数出现在条件类型左边的时候触发),以及一些特殊的类型逻辑的讲解。
学完这些套路之后,各种类型编程逻辑我们都能写。
而且,TS 也内置了不少高级类型,我们也都过了一遍。
并且我们还通过几个例子感受了下类型编程的意义:可以对已有类型做修改,可以动态生成一些类型,可以做更精准的类型检查和提示。
之后进行了一些综合的实战,综合运用上面的套路和内置的高级类型来实现了一些复杂的类型编程逻辑。
原理篇我们学习了 TS 里比较难理解的逆变、协变、双向协变、不变等概念,型变给类型系统增加了一些灵活性,这些理论知识还是要知道的。
然后我们对比了下 babel 和 tsc 编译 ts 代码的区别:babel 不会做类型检查,但是在代码产物上更有优势,可以根据 targets 指定的环境来按需编译并且引入 polyfill。而 tsc 只能指定语言版本的 target,不会做 polyfill,代码产物会更大一些,但是类型检查必须依赖它。
两者结合的方式就是用 babel(或者 swc、esbuild 等同类编译器)来编译 ts 代码,然后用 tsc --noEmit 执行类型检查。
之后我们基于 babel 插件实现了简易的 ts 类型检查,大家不用写出来,但是可以跑下代码感受下类型检查的实现原理。
之后我们通过分布式条件类型为切入点读了 TypeScript 源码,当大家对某个类型的实现有困惑的时候,可以试着从源码找找答案。
然后对于 isEqual 等类型编程中一些比较令人困惑的点集中做了说明。
类型编程的案例还是有很多的,但是都逃不开小册里的那几个套路,这就像你会了 JS 的 if else、function、for、while 就能写各种逻辑一样,把这些基础的套路掌握好了,各种类型编程逻辑都是能写的,万变不离其宗。
希望这本小册能帮助大家掌握类型编程,成为类型体操高手。