微软提议:将 TypeScript 作为注释
作者 | Kevin Vogel,译者 | 弯月
最近,微软宣布了一项举世瞩目的提案,表示他们将支持 JavaScript 和 TypeScript 的进一步开发,该提案几乎在一夜之间动摇了编程语言的基础。
截止到目前为止,该提案还只是一个处于 Stage 0 阶段的建议,但微软宣布他们会按时将该提案提交给 TC39 委员会。如果这个提案被采纳并付诸实施,那么必将在 JavaScript 和 TypeScript 界引发前所未有的动荡。
1、JavaScript 的历史回顾
回溯 20 年前,与现在的 Web 开发做比较,你就会发现,虽然 JavaScript 作为一种编程语言已经有了很大的发展,但围绕 JavaScript 的生态系统则取得了更大的进步。
语言本身与生态系统的发展是相辅相成的,一方面在过去的二十年里 JavaScript 社区变得越来越专业,而另一方面互联网本身在现实生活中的重要性也变得越来越突出。作为开发人员,我们无法控制用户使用哪些浏览器。
这意味着用户只有定期更新浏览器才能使用 JavaScript 的现代功能。虽然对于个人用户来说,定期更新并不是难事,因为如今许多浏览器会自动更新而无需用户的指示,但对于企业却并非如此。
各个公司对于软件和软件更新有着严格的规定。许多公司都会使用过时的软件或浏览器上网。这是一个基本问题,甚至会影响到 HTML 和 CSS,此外,由于编程语言必须由各个浏览器解释,因此也会对浏览器产生严重的依赖。
2、转译与捆绑
作为一名 Web 开发人员,你必须在两种思路之间做出选择:第一,依赖现代 JavaScript、CSS 或 HTML,这种方式不仅可以简化编程,而且也可以提高易用性;第二,不使用这些现代功能,因为并非所有人都使用最新的浏览器,因此采用一些现代功能可能会导致一定数量的用户无法正常使用。
除此之外,几十年来我们还没有一个像样的 JavaScript 模块系统。Node.js 从 CommonJS 借鉴了模块系统,但仅限于服务器。
在最近的很长一段时间里,浏览器都没有出现太大的提升,于是捆绑器与转译器应运而生。尽管我们使用的是 JIT(即时)编译的编程语言,但必须经过一个复杂的构建过程,将源代码转换为实际代码,然后才能在浏览器中执行和解释。
这是大约十年前的情况。
3、TypeScript 的崛起
微软推出 TypeScript 也正好是在十年前。微软认为,如果在部署代码之前,还需要一个转译器来转换 JavaScript 代码,那么在这个构建过程中再添加一个步骤也没什么大不了。
作为回报,你可以获得一个良好的转译器,将现代 JavaScript 转换成原始的 JavaScript。此外,TypeScript 是一个静态类型系统,它不仅提高了 JavaScript 的可扩展性,而且还提出了一些新概念,并为提高 JavaScript 的开发效率做出了重大贡献。
因此,TypeScript 迅速崛起,并成为当今企业 JavaScript 开发的标准。
在过去的十年里,整个世界也发生了变化。虽然仍有一部分浏览器不会自动更新,而用户使用的浏览器也不是最新版本,但这类用户的比例已经大幅下降了。
这意味着,你只需关注“常青浏览器”(指自动升级到最新版本的浏览器),那么非常有希望摆脱转译器。而且现在我们还可以使用 ESM(ECMAScript 2015 模块),这是一个基于 JavaScript 的原生模块系统,既可用于服务器端,还可用于客户端。
也就是说,我们不再需要捆绑器,至少从技术角度来看是这样。捆绑器只是构建过程中的另一个步骤,为的是优化 HTTP 请求,这样就只需从服务器加载几个大文件,而小文件的数量就大幅缩减了。
4、TypeScript 将成为一个障碍?
在这种情况下,构建过程将变得越来越简化,甚至根本不需要。微软希望将来只有一个必要的工具会保留下来,那就是 TypeScript 编译器,因为 Web 浏览器和其他 JavaScript 运行时环境无法直接运行 TypeScript。
这也就是说,届时微软的 TypeScript 会从一个非常实用的工具突然变成一个很讨人厌的东西。然而微软表示,他们不想成为障碍,相反,他们希望给予开发人员更多启发。
微软担心的结果是,JavaScript 可能会像 20 年前一样,朝着高速、直接和高效的方向发展,因为如果人们不再使用 TypeScript,那么也就不再需要转译器了。
5、将 TypeScript 集成到浏览器
最简单的解决方法就是将 TypeScript 集成到 Web 浏览器和其他运行时环境中,成为代替 JavaScript 的编程语言。从理论上讲,这也并非不可能。Deno(https://deno.land/)已经在做这方面的尝试了。
Node.js 中有一个 npm 包,名叫 ts-node,它采用了与 Deno 类似的解决方案。它会在构建/加载应用程序时将其编译到内存中,就好像可以直接运行 TypeScript,但实际上并非如此。
此外,TypeScript 语言本身如今也变得越来越复杂,微软并不希望将 TypeScript 编译器的所有功能直接集成到常见的 Web 浏览器中,因为这将是一项非常复杂的任务,需要苹果、Google、Mozilla 等公司通力合作,整合一个新的大标准。
无论这个发展方向正确与否,微软都希望回避,目前这个问题的走向尚不明朗,但这项声明表明这不是他们想要的结果。
6、中间方式:JSDoc
根据微软最近发表的建议可以看出,他们想到了另一种不同的方式。除了(a)编写原始的 JavaScript ;(b) 完全切换到 TypeScript,其实还存在第三种介于二者之间的一种中间方式。
TypeScript 允许你在 JavaScript 上分析代码,甚至可以在其中存储类型,即编写适当的 JSDoc 注释即可。对于某些公司来说,这种方式不仅可以通过 TypeScript 编译器获得类型支持,而且无需将项目完全迁移到 TypeScript。
这种方式最大的优势在于,代码仍然是纯粹的 JavaScript,不仅不需要编译,而且只需删除所有 JSDoc 注释,就可以褪去 TypeScript 的外壳。我曾使用过 JSDoc,不得不说感觉更像是 TypeScript 的廉价替代品。
需要编写的代码更多,而且非常繁琐,几乎无法实现更复杂的类型,但总比没有类型好。
7、建议:将 TypeScript 作为注释
所以微软的建议是,TypeScript 沿用 JSDoc 的套路,这样就不必编译 TypeScript 了。
类型注释和关键字(例如“public”或“private”)将成为注释,在执行 JavaScript 代码时会被忽略。这意味着,你可以编写 TypeScript,而无需将 TypeScript 编译成 JavaScript 代码。
但是,你仍然可以使用 TypeScript 编译器来触发类型检查,只不过不必编译代码来运行。而“d.ts”文件将会被淘汰,因为 JavaScript 代码中也包含这些类型。
这样,TypeScript 编译器就会变成一个可选的插件,就像 ESLint 之类的 linter,所有类型注释都不会包含在执行的代码中。
因此,该提案被称为“将 TypeScript 作为注释”。
8、将 TypeScript 作为注释的缺点
这个思路听起来不错,但我看到了一些缺点。
我们不要忘记,TypeScript 不仅包含函数参数的原始类型,而且还有接口、联合类型、类型关键字、非常复杂的类型和嵌套类型、“as”关键字、公共/私有/受保护关键字、泛型类型等等。
代码本身就包含一些注释,而且还包含两种类型的注释(单行注释和块注释),如今再加上 TypeScript,那么我们就必须不使用多种类型的注释来表达关键字。
所以,我不得不思考这是不是一个好方法,因为我很喜欢当前的解决方案,即使它并不完美。毕竟,人们选择 TypeScript 而不是使用 Flow 或 JSDoc 等替代方案是有原因的。TypeScript 比这些替代方案更受欢迎也是有其背后的原因的。
此外,我们编写代码时无法使用枚举,因为它们是值和类型的混合体。还有命名空间、TypeScript 的 JSX 支持、参数属性等,这些都无法使用。所以如果你想使用枚举,就必须编译代码;如果不想编译,就不能使用枚举。
这个建议并没有真正分割 JavaScript 与 TypeScript。我非常怀疑这是否应该成为 TypeScript 未来的发展方向。
在我看来,这种方式会导致 TypeScript 开发人员陷入混乱,并形成两个阵营。一些人坚持使用当前版本的 TypeScript,而另一些人将转战“将 TypeScript 作为注释”。
9、最后的想法
在我看来,TypeScript 的发展有两个方向:要么保持完整性,尽管所有代码都需要编译;要么给 JavaScript 创建一个可选的静态类型系统。
这意味着,TypeScript 会成为新一代的 JavaScript,但微软已经否决了这个思路。因此,我的结论是,TypeScript 不应该通过这种方式从根本上发生改变,尤其是不应该以微软目前提议或支持的方式。
未来几个月或几年内 TypeScript 究竟会如何发展,就让我们拭目以待吧。
原文链接:https://betterprogramming.pub/how-microsoft-wants-to-destroy-typescript-1f1a53b18de6