大约在两年前,我所在的一个小型的敏捷团队启动了一个全新的项目。微服务、Docker、React、Redux,这些花哨的东西都用上了。
我在这些前端技术方面有一些经验,因为我去年花了一年时间在一个由 20 多名前端开发人员开发的大型 React 项目上。这对我来说非常具有挑战性。当时我们碰到了很多问题:模型内聚性问题、代码库增长、复杂且难以维护的 API、接口不一致,难以跟踪的运行时异常。
在开始新项目之前,我决定先找到解决这些问题的方法。我想也许问题出在编程语言本身上,因为它有点太过灵活和宽容了。你可以输入任何东西,因为不需要编译,没有约束和运行前代码验证,所以捆绑包中可能会包含严重的 bug。
然后我遇到了 Flowtype 和 TypeScript。经过短暂的评估,我决定选用 TypeScript。两年之后,也就是现在,我可以告诉你——这对这个项目和我的职业生涯来说都是个不错的选择。但是,如果你认为 TypeScript 开发人员的生活从此就是一路繁花,那么你最好先读完这篇文章再说。
在本文中,我不想详细说明 TypeScripts 的特性或者深入介绍项目的搭建。我想讲的是 TypeScript 好处和缺点。我想讲述一下我在使用 TypeScript 过程中感受到的最糟糕的体验,然后再介绍一些我认为最有用的 TypeScript 特性。
因为我之前有过一些 React 和 Redux 经验,所以我想基于这些经验在新项目中使用类似的设置——Webpack、Babel、NPM 脚本、Jest、Linter,只是额外增加了 TypeScript 支持。
如果你现在面临跟我类似的情况,我可以向你保证:这绝对不只修改 Webpack 配置的一个加载器条目那么简单。我必须为 TS 提供专门的配置,用 TSLint 替换 ESLint,集成 TypeScript 加载器和 Babel,将 TS 集成到 Jest 中。
很快,一些令人失望的事情发生了。TS 配置并不简单,“复制然后测试”的策略并不是很好地总能奏效。
就连将 tsconfig.json 加入到项目中这样的事情都要仔细地参考文档。
此外,Jest 和 CSS 模块存在一些问题。你迟早也会遇到这些问题。而且不要认为现在可以抛弃 Babel 了——TypeScript 不会为新特性提供任何 polyfill,也不会将新 API 转换为旧浏览器可以理解的代码。
所以我的建议是——如果可以的话,考虑使用一些项目启动工具或支持 TS 的 CLI,把自己从繁杂的项目配置中解救出来。
我的另一个非常不愉快的体验与 TypeScript 支持的库数量有关。
如果你是 NPM 包的作者,你通常会提供随时可用的 JavaScript 包。有时候,你还会公开 ES6 源代码。如果你要让库支持 TypeScript,必须提供类型定义。简单来说就是一个包含模块、命名空间、类、方法、函数等内容的声明性文件。TypeScript 模块只能使用文件中所描述的内容,并且只能通过声明中所指定的方式使用它们。可惜的是,源代码和声明文件之间通常没有严格的联系。它们可能无法保持一致,或者过时了,或者丢失了。
对于我来说,丢失声明并不是个大问题。大多数流行库的作者或社区都会准备好类型定义。如果你使用的包没有这样的文件,就使用其他的,NPM 上有很多包提供了相同的功能。你也可以自己准备“虚拟”的定义,或自己创建定义,并贡献给开源社区。
但不管怎样,还有另一个更严重的问题——一些声明是不正确的,或者过时了。如果你遇到这样的问题,要解决这个问题就没那么容易了。你可以使用旧版本的包,或者自行进行修复,或者等待作者更新。不过有时候他们反应很快,有时候也很慢。
顺便说一句,我也是一些简单包的作者。相信我,即使开发包的意愿是好的,我仍然难免会忘记将新特性与类型定义进行同步。
现在说一些好的方面吧。在搭建好项目并选择了具有良好 TS 支持的库之后,就可以享受类型语言所带来的强大功能了。如果你没有使用这门语言的经历,在一开始可能感觉有点奇怪。TypeScript 中有许多特性在当前的 JavaScript 中是没有的。接下来我将介绍在我看来最有用的一些特性。
静态类型是 TS 最常用的特性。如果不使用严格类型,那么使用 TypeScript 就没有意义了。当然,你也可以使用宽容的“any”类型,这意味着“我不关心那个东西是什么类型,它可能是一个数字,也可能是一个字符串数组”。但说实在的,如果你想这样写代码,好不如直接使用 JavaScript。
类型可以提升编码速度,写出更安全的代码。你可以告诉编译器:“这个常量将指向一个数字”,如果你试图将其用作数组或字符串,TS 编译器会提示错误。基本上,你仍然可以使用这些对象做任何你想做的事情,就像在 JavaScript 中一样,只是现在你的操作比以前更安全、更容易理解了。
在下面你可以看到一些基本但非常强大的东西,对于更高级的类型,请参考文档:
https://www.typescriptlang.org/docs/handbook/advanced-types.html。
除了众所周知的类型,如数字或字符串,TypeScript 还提供了枚举。
你可以使用内置类型,如 Date 或 Error。借助代码提示可以以实现更快、更安全的编程。
如果你认为类型是“游戏规则改变者”,那么接口呢?接口可以帮你写出更好的代码,因为你可以用它们定义对象之间的契约。我创建了很多接口,它们无处不在。有时我会把接口放在专门的文件中。
我主要使用接口来描述对象、类、函数和参数。你也可以在模块之间共享它们,并像处理源代码中的实体一样对待它们。你只需要记住——运行时没有接口,这点很容易被忘记。这就是为什么在某些情况下使用类而不是接口(例如 Angular 的依赖注入)会更好。让我们看一下接口的一些真实例子:
在左边——错误的返回类型实现。在右边——VS Code 立即会告诉你代码中存在的错误。
在左边——一个类错误地实现了扩展了 User 接口的 Driver 接口(参见上图)。在右边——错误信息。
ES6 提供了类,所以你之前可能已经用过它们。但在 TypeScript 中,类提供了一些额外的特性,它们有可能也会出现在 EcmaScript 的未来版本中。在 TS 中,你可以定义抽象类,可以将类属性描述为静态、私有或只读的,可以扩展类并让类实现接口。我不想详细描述 TS 类和 ES6 类之间的差异,因为到最后它们都会产生相似的 JavaScript 代码(在编译和转换之后)。在 TS 中,类是一种用来优雅而有效封装代码职责的方式,它们与其他语言实现(如 Java)非常相似。
当然,TypeScript 中还有很多新的东西,比如泛型(你会用到它们的)、枚举(可能会在内部用到)、名称空间、JSX 支持,等等。但你不需要在一开始就全盘使用它们,只需要使用上面提到的基本特性就能让你的代码质量得到提高。
在 TypeScript 中,你可以使用抽象类等特性。有关抽象类的更多信息请参阅
https://www.typescriptlang.org/docs/handbook/classes.html。
TypeScript 支持 private、public 和 protected 方法和只读属性。类可以实现接口或扩展其他类。
为什么说使用 TypeScript 可以提升代码质量呢?
-
可以避免一些非常烦人的运行时错误,这些错误是因为参数名或变量名输入错误导致的;
-
你可以在对象之间创建清晰的契约;
-
可以很自然地实现私有成员或类;
-
编译器会立即给出反馈,很多错误都可以在编译阶段捕获,而不是在运行时;
-
非 JS 开发人员更容易阅读和理解代码;
-
你可以使用未来版本的 JavaScript 才会提供的特性;
-
可以更容易地为进行单元测试(打桩),因为你知道它们的接口是怎样的。
此外,因为 IDE 提供了很好的支持,编写可维护的代码要容易得多。说实话,即使你是独自开发一个中小型应用程序,在几周后也很难记得某个函数的参数类型或新创建的接口是怎样的。你可以翻出代码查看。不过,如果你只需要在编辑器中将鼠标悬停在函数名称上就可以看到它的参数岂不是更好?例如,这个函数接受“age”作为参数,它是一个“数字”,并返回一个包含“age”和“name”属性的 User 实例。
我还想说另一个东西,那就是代码评审。当你处在一个小团队中时,你可能是唯一的一个前端开发人员,其他熟悉.net 或 Java 的团队成员看不惯 JavaScript 代码。没有类型意味着没有提示。例如——“user”对象有一个“ID”属性,但它是数字还是字符串呢?如果是一个字符串,为什么你还要调用“toString()”方法呢?如果是一个数字,为什么你要在它前面添加字符串“id_”呢?TypeScript 看起来很像其他流行的类型编程语言,而且你会获得更好、更准确的代码评审,而更好的代码评审意味着更好的代码质量。
在左边——TypeScript 代码。在右边——Java 代码。它们的语法非常相似,这意味着你的代码应该更容易被 Java 开发人员理解。
最后,我还想说一些关于 TypeScript 的话。当你尝试新事物时,总会有学习曲线问题。TS 的学习曲线不是非常陡峭,但也不是很平坦。在两年前,我选择了 TS,我认为这是一个很好的学习一门有前途的语言的机会。我很确定,如果我当时选择了其他框架(比如 Angular)和其他语言,我会感到失望和沮丧。
TypeScript 值不值得推荐?我当然觉得值得。它可以帮助你在更短的时间内写出更好的代码。IDE 对它的支持非常棒,社区充满活力,包含 TS 定义的库足够多,而且在不断增长,开发者体验也很好。这是我所知道的用于创建现代和可扩展 Web 应用程序的最佳工具。但也请记住上面提到的一些缺点,绕开这些问题,并在多彩的静态类型语言世界中遨游吧。
英文原文
https://ecom.software/en/after-two-years-with-typescript-was-it-worth-it/
点个在看少个 bug ?
文章评论