关于TS的思考
JS 是一门脚本语言,也是一个非常灵活的语言。
灵活是一把双刃剑,一方面他让作者可以写更少的代码,一方面又增加读者理解代码的难度。
随着时代的发展,JS 的使用量逐渐扩大。这时一个能帮助我们写出更容易维护的 JS 代码的工具就显得非常必要了。
时代催生了两个知名项目来实现这个目标,一个是 Facebook 的 Flowjs,一个是 Microsoft 的 TS。
他们选择了相似但又有区别的技术路线。
- Flowjs 倾向于保留 JS 的所有灵活性,让工具去适应这种灵活性。
- TS 则倾向于先限制部分 JS 的灵活性,并在工具稳定支持的前提下逐步放开限制。
在多年竞争后,TS 赢得了市场的认可,而 Flowjs 逐渐淘汰,这也意味着从商业产品角度,TS 的路线是比 Flowjs 更正确的。
目前仍有部分人认为 TS 限制太多,他们倾向于编写传统的 JS 代码。那其实本质原因并不是 TS 不够好,而是 TS 给他们带来的功能并不足以说服他编写额外的代码。
TS 设计理念
TS 的设计理念是务实,这点我是非常认可的。
务实设计点1:宽松的类型校验
var a: 动物[] = []
var b: 猫[] = a // 将“动物[]”转为“猫[]”,是正确的转换吗?
有一些人认为 TS 的类型不够严谨,于是就做了一些 TS 改版,以使得校验更“正确”,但事实证明这些项目都失败了。
根本原因是:除非直接运行代码,否则我们是无法 100% 准确推测类型是否正确的。
从编译器角度,我们分析代码可以得到四种结论:
- 代码一定是对的
- 代码一定是错的
- 代码可能是对的,也可能是错的
对于前两者场景,编译器一定需要报错或不报。而对于第三个场景,编译器要不要报错,取决于设计者的权衡。
如果类型校验做到绝对严谨,意味着对于“代码可能是对的”也会报错,而这无疑增加了用户排错的成本。
TS 的权衡宗旨是:
- 不要对很可能是对的代码报错,这会让用户厌恶。
- 编译器报错的代码,最好真的就是一个 BUG,这会让用户喜欢上 TS。
- 如果编译器报错了,一定要留一条后路,方便用户解决报错。
务实设计点2:分发条件类型
如果不是 TS 的深度用户,可能看不懂“分发条件类型”。
但 TS 的巧妙就在用户可能正在使用“分发条件类型”,但又不需要知道“分发条件类型”是什么。
分发条件类型是指条件类型在判断填充为联合类型时的泛型时,会有特殊处理。
这种处理可能导致有些场景的无规律或难以理解,但在多数场景下,他都符合用户预期。