翻译:疯狂的技术宅
作者:Paul Cowan
来源:logrocket
正文共:2005 字
预计阅读时间:7 分钟
在开始之前,希望大家知道,我是 TypeScript 爱好者。它是我在前端 React 项目和基于后端 Node 工作时的主要编程语言。但我确实有一些疑惑,所以想在本文中进行讨论。迄今为止,我已经用 TypeScript 写了至少三年的代码,所以 TypeScript 做得的确不错,而且满足了我的需求。
TypeScript 克服了一些很难解决的问题,并成为前端编程领域的主流。TypeScript 在这篇列出了最受欢迎的编程语言的文章【https://www.agiratech.com/most-in-demand-programming-languages-learn-2020/】中排名第七位。
无论是否使用 TypeScript,任何规模的开发团队都应该遵循以下惯例:
编写良好的单元测试——应在合理范围内涵盖尽可能多的生产代码
结对编程——额外的审视可以捕捉到的错误远远超过语法错误
良好的同行评审流程——正确的同行评审可以检查出许多机器无法捕获的错误
使用 linter,例如 eslint
TypeScript 可以在这些基础之上增加额外的安全性,但我认为这在编程语言需求列表中应该排在后面。
TypeScript 不是健全的类型系统
我认为这可能是 TypeScript 当前版本的主要问题,但是首先让我定义 健全 和 非健全 的类型系统。
健全性
健全的类型系统是能够确保你的程序不会进入无效状态的系统。例如,如果表达式中的静态类型为 string
,则在运行时,要保证在评估它时仅获得 string
。
在健全的类型系统中,绝对不会在编译时或运行时产生表达式与预期类型不匹配的情况。
当然 TypeScript 有一定程度的健全性,并捕获以下类型错误:
1
不健全
100% 的健全性不是 Typescript 的目标,这是在 non-goals of TypeScript【https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals】列表中第 3 条中明确指出的事实:
…适用健全或“证明正确的”类型的系统。相反,要在正确性和生产率之间取得平衡。
这意味着不能保证变量在运行时具有定义的类型。我可以用下面的例子来说明这一点:
1interface A {
上面的代码是 不健全 的,因为从接口 A
中能够知道 a.x
是一个数字。不幸的是,经过一系列重新分配后,它最终以字符串形式出现,并且以下代码能够编译通过,但是会在运行时出错。
不幸的是,这里显示的表达式可以正确编译:
1a.x.toFixed(
我认为这可能是 TypeScript 最大的问题,因为健全性不是目标。我仍然会遇到许多运行时错误,tsc
编译器不会标记这些错误。通过这种方法,TypeScript 在健全和不健全的阵营中脚踏两只船。这种半途而废的现象是通过 any
类型强制执行的,我将在后面提到。
我仍然需要编写很多的测试,这让我感到沮丧。当我第一次开始使用 TypeScript 时错误地得出结论:可以不必编写这么多单元测试了。
TypeScript 挑战了现状,并声称降低使用类型的认知开销比类型健全性更重要。
我能够理解为什么 TypesScript 会走这条路,并且有一个论点指出,如果健全类型系统能够得到 100% 的保证,那么对 TypeScript 的使用率讲不会那么高。这种观点随着 dart 语言的逐渐流行( Flutter 现已被广泛使用)被反驳了。健全性是 dart 语言的目标,这里是相关的讨论(https://dart.dev/guides/language/sound-dart)。
不健全以及 TypeScript 暴露在严格类型之外的各种转义符使它的有效性大大降低,不过这总比没有强一些。我的愿望是,随着 TypeScript 的流行,能够有更多的编译器选项可供使用,从而使高级用户可以得到 100% 的可靠性。
TypeScript 不保证运行时的类型检查
运行时类型检查不是 TypeScript 的目标,因此这种愿望可能永远不会实现。例如在处理从 API 调用返回的 JSON 时,运行时类型检查将是有好处的。如果可以在类型级别上进行控制,则不需要那么多的错误种类和单元测试。
正是因为无法在运行时保证所有的事情,所以可能会发生:
1
尽管有一些很棒的支持库,例如 io-ts,但这可能意味着你必须复制自己的model。
可怕的 `any` 类型和严格性选项
any
类型就是这样,编译器允许任何操作或赋值。
TypeScript 在一些小细节上往往很好用,但是人们倾向于在 any
类型上花费很多时间。我最近在一个 Angular 项目中工作,看到很多这样的代码:
1
TypeScript 让你忘记类型系统。
你可以用 any
强制转换任何一种类型:
1(
strict
编译器选项启用了以下编译器设置,这些设置会使事情听起来更加合理:
--strictNullChecks
--noImplicitAny
--noImplicitThis
--alwaysStrict
还有 eslint 规则 @typescript-eslint/no-explicit-any【https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-explicit-any.md】。
any
的泛滥会破坏你类型的健全性。
结论
必须重申,我是 TypeScript 爱好者,而且一直在日常工作中使用它,但是我确实认为它出现的时间还很短,而且类型还并不完全合理。Airbnb 声称 TypeScript 可以阻止 38% 的错误【https://www.reddit.com/r/typescript/comments/aofcik/38_of_bugs_at_airbnb_could_have_been_prevented_by/】。我非常怀疑这个数字的准确性。TypeScript 不会对现有的做法有良好的提高。我仍然必须编写尽可能多的测试。你可能会不同意,不过我一直在编写更多的代码,并且不得不去编写类型测试,同时仍然会遇到意外的运行时错误。
TypeScript 提供了基本的类型检查,但健全性和运行时类型检查不是它的目标,这使 TypeScript 在美好的世界和我们所处的现状中采取折衷。
TypeScript 的亮点在于有良好的 IDE 支持,例如 vscode,如果我们输入了错误的内容,将会获得很好的视觉反馈。
通过 TypeScript 还可以增强重构的功能,并且在对修改后的代码进行编译时,可以立即识别出代码的改变(例如方法签名的更改)。
TypeScript 启用了良好的类型检查,并且绝对要比没有类型检查或仅使用普通的 eslint 更好,但是我认为它还可以做更多的事情。对于那些想要更多的人来说,还能够提供足够多的编译器选项。
原文:https://blog.logrocket.com/is-typescript-worth-it/
2020年京程一灯全新课程体系即将推出,请保持关注。
愿你在新的一年里保持技术领先,有个好前程,愿你月薪30K。我们是认真的 !
✎往期精彩回顾
面向开发人员的十大 NodeJS 框架
JavaScript 类完整指南
讲给前端的正则表达式
WebAssembly 正式成为 Web 的第四种语言
2020 年 Node.js 将会有哪些新功能
2020 年 Web 开发展望
从 JavaScript、ES6、ES7 到 ES10,你学到哪儿了?
15个 Vue.js 高级面试题