如何选择TypeScript 或是 JavaScript?
JavaScript的基础打得够扎实了,开始关注 TypeScript。在读到一些对比文章和图书导论后,我的第一直觉是,TypeScript和JavaScript的关系就像,OOP和FP,CSS 里 flexbox和NP的关系相似,它们不是互相吃掉谁的关系,是完成同一种任务的两种特别设计的工具。也就是说,TypeScript不是替代JS,而是用来开发不适宜使用JS开发的项目。这里理解的关键是,编程语言作为一个工具(一种比 编程范式更高级别的工具)是可以如何被设计的,就像编程范式的两种不同设计思想,产生OOP和FP编程。
编程语言作为一种工具,它有一个类型系统(typing)的属性,这个属性影响你以何种方式编程(编程算法的分析和表达),这个工具属性影响你编写程序(任务)的效率和效果,包括设计,分析,开发和维护等任务。
我觉得这篇文章(《TypeScript vs JavaScript: A Fight for the Web》)比较精简,略译出来。
在文中,TypeScript 所声称的好处:编译时查错,大项目组织性(防乱),程序功能健壮性等是怎么实现的,这是个很关键,有趣的问题。回答这些问题,需要认识 程序构建的本质,例如为什么需要类型信息(类型信息可预期?)
其实1)编译时查错:这个比较容易解释;2)代码组织性,我能想到的是,第一,IDE的提示;第二,编码风格更容易统一化;3)功能健壮性,则是以牺牲可读性 易用性为代价,具体原理还得再分析。
TypeScript vs JavaScript: A Fight for the Web
by Ethan ScullyJan 15, 2020
JavaScript 是地球上最流行的程序开发语言之一,截至2018年,有95%的网站使用 JavaScript开发。不过,已经有人认为 JavaScript 已经跟不上时代了,是时候有一种新语言替代JavaScript,这就是TypeScript,持这种观点的当然是TypeScript的设计者们。
本文大略分析一下这两种语言的区别,从中你将看它们的关系(包括工具特性的优劣),并且在当下或未来,在「项目开发的语言选择」上有一个客观的参考。
JavaScript
JavaScript 诞生于1995年,是一种现代高级的(high level)、多范型(multi-paradigm)、即时编译( just in time compiled)运行的程序语言。JS应用程序可以即时编译运行在浏览器上,也可以即时编译运行在 Node平台环境上。
另外,JavaScript还有一项重要特质,就是它是 一种 动态类型(或弱类型)的编程语言。动态类型(dynamically typed)是意思是,你可在编程时(源码里)不用指定数据的类型信息[em],数据的类型会在运行时确定。
TypeScript
TypeScript 则年轻许多,它诞生于2012年。TypeScript 并不是一种全新的独特的语言,而是 JavaScript 的现有的功能的补充,称为超集;就是在JavaScript的工具特色或特性(features)基础上,再添加新特性。
C和C++ 就是“超集”关系的一个例子,C++只是个带“类”的C。同理,TypeScript只是一种带有强类型语法,类(配带一些其他的优化)等的 JavaScript。事实上,TypeScript 的编译器只是将 TypeScript 代码 转化为 普通的 JavaScript代码。
JavaScript vs TypeScript
所以,哪一种更好?TypeScript发展的哲学原因在哪里?我们来对比一下。
类型系统属性和语法
JavaScript 的设计初衷是,宽松、易用和自由。而 动态类型 是这种设计重要体现,动态类型 是说,你在编程分析的时候不必过分关注 数据的类型信息,集中注意在算法逻辑上。由于卸载了部分思维负载,故会较容易编程推理,代码也简单。
这听上去是个优点呀!不像是什么缺点。这在只有你一个人和一个较小的项目上,是优点。但是如果是团队开发的复杂项目,这种“自由”负面代价更大。
如果一支团队中每个人都按照自己自由的风格(任意忽视类型)去开发,那么最终的代码库只会变很难阅读,开发和维护[em]。项目越大,代码越乱。别说是他人接手代码,甚至是自己开发的代码一段时间回头可能都会忘记算法原意。
EM:前面说,JS 的简单自由易用,这里又说难读难维护?矛盾在哪里?就是说,大项目和JS的任意性的冲突在哪里?
TypeScript 类型系统设计
这就是 TypeScript 设计和发展的哲学原因。TypeScript提供了一套 灵活健壮(robust)的类型系统:
- 支持常用静态类型
- 类
- 结构式类型(structural typing)注
TypeScript 是完全兼容 JavaScript 代码的,这是 TypeScript 最大的一个优点。TypeScript 只是一个超集,原JavaScript 代码完全可用,编程方式完全不变,只是多一些特性可用。
如果你还没有掌握或精通 JavaScript 的使用,TypeScript 和 JavaScript 的这种关系可能在你学习TypeScript造成一定的困惑,和迟疑。JavaScript没有类型限制,出了名的易学易用,初学者会不理解现在又给JavaScript添加类型限定的意义em。其实,自由方便 (freedom)和 具组织性(organization)是相冲突的,对于刚入门的人来说,更需要自由、方便和简单,而对于专业大型项目则不一定。
代码可读性与程序功能健壮性
TypeScript 的类型系统能让 程序代码更具组织性,功能实现也更具健壮性(Robustness)注2,然则也有代价。代价就是 代码可读性下降。
代码可读性的感受是主观的,因人而异,但大多数程序员同意当 代码越杂乱(cluttered code),可读性越差。
TypeScript添加类型系统意味着,我们需要编写多几行额外代码来维护“程序的类型”,例如,当我们编写新功能时,需要数据变量,除是声明它的名字,还中考虑(声明)它的类型信息,花了时间,和代码量。「代码功能的健壮性」需要牺牲 可读性,也就是更多的脑力分析,这道理很合理。
兼容性
由上可知道,TypeScript 几乎就是 JavaScript,真正的不同,是那些需要用「类型系统功能」去阅读和分析代码的人,才能感觉出来。
怎么选择?
虽然 TypeScript 为 JavaScript增添一些很有价值的工具特性(features),但并不意味着所有人所有项目都需要迁移到TypeScript。如果你的项目比较小,或者只有一个人开发,那TypeScript有可能不适用,脑力投入可能不值。
相反,如果你有一支较大的项目和团队,尤其是维护频率和演化大的项目,TypeScript应该是最佳的选择。
- 什么是 structural typing The basic rule for TypeScript’s structural type system is that x is compatible with y if y has at least the same members as x. TypeScript uses structural typing. The idea behind structural typing is that two types are compatible if their members are compatible.↩
- 其实最大的原因,是对「语言的类型系统属性」的意义——工具特性的意义——的认识不足造成的。↩
- 什么是程序的健壮性或稳健性(Robustness) 程序的健壮性就是指程序处理问题的一种能力。这种能力是指程序在面对无效的输入或者是在某些外在压力的情况下,系统能够正确解决问题的程度。↩