TypeScript 哲学三问
引
从 TypeScript 的 0.8.0 的第一次亮相到现在马上就要十一年了,一个纪录片介绍了 TypeScript 是如何诞生又是如何发展的,基于这个纪录片谈一谈我对它的哲学三问:它是谁?从哪来?到哪去?
正文
TypeScript 生来便与众不同,在其他的无静态类型语言(Python、Lua…)还在蛮荒时代时,它如同一道劈开宇宙的闪电出现在世界。
JavaScript 的困境
那么到底出现了什么问题呢,为什么说 JavaScript (甚至诸如此类的语言)是有问题的?
「你无法想象我在写完一个 8000 行的 JavaScript 代码后我应该如何去维护它。」
「在六个月后回到这个项目我无法找回开发时的状态。」
「为什么我要去猜测、去记住一个变量是什么类型?」
「你知道的,我记性不好,我并不想记住那些复杂的 API 名称。」
从何开始
在故事的最开始 TypeScript 只是设计用来给 Visual Studio 进行编码辅助工具,听起来有点类似于 Kotlin 是设计出来为了给 JetBrains 给 IDEA 提供更好的编码的工具。
但是,TypeScript 和 Kotlin 有着最根本的区别,TypeScript 是作为 JavaScript 的超集而存在的语言,而 JavaScript 并不存在类型信息,运行时也不会去思考这个类型的变量在内存里面是什么形状。TypeScript 它实际上是尝试去修复 JavaScript 而不是去替代 JavaScript,在同一个时代与 Kotlin 之于 Java 一样的,也有 Dart 之于 JavaScript 这样的替代品。甚至在那个年代还有为了不写 JavaScript 而专门开发了从一个已有的语言 C# 转译到 JavaScript 的工具。
而 TypeScript 所需要解决的问题也不同于他们,它是为了修复 JavaScript 无法进行真正的可控大型项目开发的问题:
「我们如何找到这个变量、函数、文件被谁引用了。」
「这个变量是否能附加上我们所需要的信息,是否存在其他的传入冲突。」
「在我们需要的地方我们能不能安全的去解决我们的结构性重构安全。」
「我为什么需要记住多如牛毛的仓库的调用 API 以及传入参数。」
它作为一个工具直接改变了软件开发的思维方式,它让你的变量的信息在编辑器与它的加持下能变得更加的简单,也更容易去对他进行操作。
打破惯性
它也打破了传统 IDE 对于像 JavaScript 这一类语言的处理方式,就像 JetBrains 的 WebStorm 会将代码作为文本一样去使用自己的分析工具去对他进行处理,他们只会尽可能去遵循运行时的语法对你的代码进行推测,但是我们可以看到这种对于代码的推测是很不准确的,对开发者的帮助也十分的有限,但是当我们在 VSCode 编写 TypeScript 或者是使用支持 TypeScript 的工具时,我们可以发现它对我们的提示甚至比我们在(在未集成 TypeScript 服务时)传统 IDE 下还要强大。
在当时这是一种全新的思考方式,通过这种方式我们能使得我们的编辑器更加的智能,在 TypeScript 之后我们也看到了微软把这种成熟的形式投入到了 Python 之中,在 Python 3.8 后修复了没有类型带来的问题。
如果你想知道没有类型提示的 JavaScript 是什么样子的?来试试 Python 3.5 吧。
孩子的第一个开源项目
相比于当时的开源环境,那个年代的微软在开源上毫无作为,甚至经常弄一些不成体系的项目来戏弄开发者(竞争市场成功后又把项目抛弃)。而现在我们看来微软相对于其他的公司可以说是真正的开源先锋了,那么他们又是怎么做到的呢?
一开始像 TypeScript 这样的项目是绝对不可能免费甚至开源作为一个基础工具提供到用户,在当时的很多的公司商业模式还在多卖 license,做更多的软件出来售卖。然而 TypeScript 在那个时候恰好遇到了时代的转变,微软的主要商业模式从软件转移到了云,这很大的程度的促进了 TypeScript 的开源以及在后面对 VSCode 到 .Net 的开源策略推进与借鉴。
如果当时微软没有一个像 TypeScript 这么成熟的开源项目,那么可想而之对于微软收购 GitHub 会遇到多大的阻力。
决定性的生态
在 TypeScript 的发展过程中有一些附属生态对他的推广起到十分重要的作用,一个是对现有无类型仓库的类型支持,一个是对于现有前端框架的支持。前者在前期产生了一个抉择,到底是使用 DefinitelyTyped 还是 typings,在最后社区选择了使用前者,从而促进其成为了 GitHub 上更新与维护最为频繁的项目(每天都有新的包和新的版本发布)。
对于框架的支持,TypeScript 团队一直致力于多方合作赋能共建,他们的第一个目标便是 Angular.js。Angular.js 也苦于 JavaScript 的类型困境与编译问题,自研了 atscript 作为他们的开发语言,但是这并不是他们想做的事情,他们想做的只是开发一个框架,而不是去开发一个新的语言,在这个时候 TypeScript 主动找到了他们,与他们合作,不过这个时候社区中也存在着 Flow、Dart 此类的方案,经过他们会议探讨,只有 TypeScript team 希望参与的想法最为强烈。最后他们选择了 TypeScript ,历史证明这也是一个正确的决定。在此之后,TypeScript 相继推进了对 React 的 JSX 的支持,以及与 EvanYou 的合作。
在框架之外,TypeScript 对于 ECMAScript(JavaScript) 也有着推进,他们由 Optional Chain 提案逐步走向了与标准制定的 TC39 深度合作。
杂谈
其实 TypeScript 也并不是严格意义的超集,他有超过当时时代的设计。有类,有装饰器等超过当时 JavaScript 发展的内容,从而他也承担了一定的 Babel 此类工具所做的工作。这些功能也促进了 TypeScript 的功能的完备,以及对标准的推动(虽然没几个真的推成功的【笑】)。
总会有人说:“Svelte 和 Webpack 这样的大型项目抛弃了 TypeScript ?”
那么这个问题的回答便是:“不,他们只是在使用我们开发另外一种 TypeScript(JSDoc)。”
对于大多数 JavaScript 生态下的仓库开发者来说有一件事挺重要的「如果我只需要将我的类型标注上,我所有的用户都会收到收益,那么我为什么不去做呢?」这也是我一直所认同的观点,只要我的代码有使用者(调用者、维护者),那么他就是有意义且重要的,我编写我负责。
到哪里去
基于编辑器的人体工程学对无类型信息的语言进行类型系统设计或许是真正的契合开发者体验的一种设计方式,扩展到对任意类似代码的文本进行分析的工具从而诞生的 LSP(Laguage Server Protocol)应该是任何现代化的语言不得不走的一条路了。如果一个语言没有这一套生态,已经很难在现有体系内获取到足够的开发者进来参与(比如死掉的 Flow.js)。
结语
愿每一个伟大的开源人都能获得他所想要的,在开源共享合作的精神下能获得了我们不被异化的劳动意义,那就是同类的认可、对同类的帮助。
感谢 TypeScript Team 为大家做的一切。
相关
转载自:https://juejin.cn/post/7281465630493458443