最近在写 Angular ,众所周知,现在要写 Angular 基本上是除了 TypeScript 就没得跑了。不得不说, Angular 真是前端规范化的练兵场,前端三大框架中,唯 Angular 严格控制了编写的方式,从环境搭建到部署发布, Angular 很省心地处理了其中的大部分问题,使得你可以专心业务,在这一点上,学习 Angular 的 NestJS 还是差很多的。

但话说回来,我是要讲 Angular 的 TypeScript 体验的。我之前是有写过几次 ts 的,比如用 NestJS 还有 Vue3 ,体验都不尽如人意,我也很难体会到 ts 的好处。但这次在 Angular 上的 ts 体验却是出奇的好,我就在此总结一些东西。

为什么不用 TypeScript ?

使用 ts 你就不得不面对第一个难题——类型。

类型是 ts 的特性,但也是麻烦所在,尤其是从 js 项目转过来的时候,过于灵活的对象操作导致你无法精确定义类型。这个时候我们可以选择用 any 来解决这一难题,但这实际上就造成了另一个问题:我们实际上抛弃他的潜在类型。

一切的问题的根本要点在于,代码的初始设计根本不是基于 ts 开始的。从我个人角度而言,与其将这些代码费劲巴拉地转换为 any 横行的 ts ,不如直接用 js ,然后用 .d.ts 去做兼容,后续用 ts 的思想逐渐替换。

所以,为什么不用 ts ,当我们没有准备类型的时候,我们就不应该过多地思考去使用 ts 。想使用新特性用 babel 就可以,类型提示很多编辑器都可以做到,但是如果你没有相应的类型思想,类型最多给你是负担。所以,为什么不用 js 呢?

为什么使用 TypeScript ?

ts 就是为了解决 js 的一大痛点而诞生的——类型。

ts 的类型之于 js 不过是一层皮,即使 ts 类型不对, js 也能被强行生成。所以,如果使用者不遵循类型规范,其实 ts 的类型约束就是形同虚设。所以问题在于,为什么需要类型?

一个最最基本的论点是出于工程化的需要。因为 js 的动态能力会给与使用者不可预料的问题,而即使使用者是本人,随着工程越来越大,人也无法处理其中繁杂的各种情况。因此,约束 js 的动态能力是必要的。而 ts 本质上就是将静态语言的静态性赋予了 js 同时不使得 js 失去动态能力。

除此之外, ts 也方便了 IDE 对代码进行分析,对于很多人来说,这才是主要的。

AnyScript

我其实不推荐为了 IDE 对于 ts 的分析而使用 ts ,因为显而易见地,你如果不写类型,这个分析最后还是形同虚设的。

不要小瞧 IDE 对于 js 的分析,现在很多库也都写了 ts 的支持,使得你在 js 下也能有对应的补全,你如果使用 flow 配合 jsdoc 的注释,其实写 js 也能有不错的体验。所以,我在写小文件、小项目时仍倾向于用 js ,因为此时 ts 的类型对我负担太大。

但这时会有人说,用 any 不就好了吗?

确实, any 可以解决几乎一切问题,但最后留给你的是一堆与 js 无异的 ts 代码,写得还束手束脚的。any 几乎是将 ts 写得稀烂的必要因素,好好的 TypeScript 写成了 AnyScript 。但是这个问题是怎样造成的呢?

首先 ts 有自动类型推导,但是 ts 的自动类型推导不能完全推导出正确的类型,而那些有问题的推导一旦被改为 any 就会导致类型推导的连锁反应,比起其他类型, any 是会传染的,一处用了 any ,如果其他地方不加限制,那么最终会演变成处处 any

如何良好地编写类型

其实如果在任何地方都编写一个类型,其实是很繁琐的一个过程。我觉得是否需要编写,应该遵循一个尽可能简单的原则,我倾向于实现所有我们需要用到的类型及其中需要被使用到的字段,其他的部分我们暂时可以忽略或者无视,等到我们需要的时候再加以实现。

为什么这么处理呢?因为很多类型是我们是不关心的,而我们用到的类型我们时常需要打交道,因此我们至少要明白我们常用的类型是什么内容。

另外,我们也应该尽量使用现有的类型编写代码,这不仅仅是为了减少类型的编写,也是为了提高类型的复用,降低心智负担,提高对“类型-业务”这一模型的理解。很多人嫌写类型繁琐,往往就出在对类型低复用导致类型出现大量冗余。

最后,我们的类型需要在哪些地方被标记?毫无疑问,方法的输入输出、导出的变量我们都需要编写类型,这些地方除非特殊情况,尽量不要用 any ,类型可以多使用组合类型以增加类型复用,另外也多善用重载功能。类型待定的情况下最好使用模板而不是 any ,换句话说,尽量让类型可传导可推断而少出现 any

结语

这是我这一段时间使用 TypeScript 的经验谈,通过这一段时间的使用,我已经享受到了 TypeScript 在项目中开发的快乐,虽然如此,我仍然会选择视情况而定。诚然, TypeScript 有诸多好处,但最终 TypeScript 仍然是要被编译成 JavaScript 的,在大项目中,如果来不及做注释的话, TypeScript 确实是更好的选择,但小项目中,原生其实没有你想的那么难堪。