前言
最近几年, 纷纷涌现typescript被社区放弃
的言论, 主要以这几个项目为主:
这三大项目的决定纷纷让社区里出现了typescript不值得了
等的相关言论, 但实际上typescript
真的不值得了吗? 接下来, 就从我的调研和认知层面向大家分析分析 ------ typescript真的不值得了吗?
我始终觉得社区大多数人对这些项目作者的观点有着不太准确的解读 (或过分解读)
1,svelte
svelte的观点很明确, 放弃typescript是因为typescript带来的构建问题, 而且大佬很贴心的怕我们误解: 对应用程序来说没这方面的问题.
svelte放弃typescript并非typescript本身不好, 这就归结于第三方库的调试成本问题了:
svelte是mvvm的框架, 对于svelte的开发维护者们来说, 需要经常在浏览器上经常调试代码, 而经常开发第三方库的小伙伴应该知道, 如果你写的第三方库的源码不能直接跑, 那调试成本会非常大, 每次改一处代码, 想看看运行结果, 都需要build后等待运行结果, 那真的要老命.
但不仅仅是typescript会代码构建上的问题, 开发环境的浏览器上不支持的语法, api等, 同样也会有代码构建的负担.
注: 调试的时候跑源码, 不代表最终上传npm包时真的不需要构建代码, 把第三方库打包成兼容性更好的代码, 对用户使用时的体验来说是很优秀的决定.
不懂调试成本的小伙伴也不要慌, 只需要知道第三方库的开发和项目中的开发需要注意的点不一样就行了, svelte的观点与你们的开发无关.
但svelte真的放弃typescript了吗, 如果没放弃, 那它究竟放弃了什么?
来看看svelte的源码截图:
正如svelte的大佬所说, 我们可以看到, 源码彻彻底底从typescript代码转为javascript + jsdoc + .d.ts + ts.config.js了, 源码的类型是变了, 但typescript的一系列功能却还保留着:
- 利用ts.config.js提供typescript的类型校验功能
- 利用.d.ts进行核心的typescript类型声明和类型编程
- 利用jsdoc进行少量的类型编程
- 最终构建.d.ts文件
以上的部分jsdoc语法是typescript语法, jsdoc官方有解释, 例如
@type {import('xxx').XXX}
, 甚至jsdoc的一些新用法, 基本都是借鉴typescript的, 可以看作jsdoc是typescript的一种承载体, 但vscode等ide内部的语言服务, 核心仍然用着typescript
这么看来, svelte官网是换汤不换药, typescript仍然没有放弃, 放弃的只是typescript对于第三方库带来的维护成本而已.
svelte引发的更深刻思考
typescript等高级语法或api对第三方库带来的维护成本而言, 难道只能通过放弃typescript源码编程的方式来解决了吗?
思考到问题本源, 不过是浏览器不支持这些代码而已 (node是不支持, 但deno却是支持的, 所以只需要考虑浏览器), 但我们是否能实现浏览器垫片, 通过浏览器插件的形式, 让浏览器支持这些代码? 或者浏览器本身能支持typescript?
可以看到浏览器对于typescript代码支持的功能已经有提案了: devblogs.microsoft.com/typescript/...
相信这个提案最终大概率会被确定下来, 毕竟对于第三方库开发者而言, 这个真的非常重要, 而在不久的将来, 说不定svelte官方会再次将javascript源码转为typescript源码.
2. deno
deno本身就支持typescript, 想通过deno源码放弃typescript曲解成typescript本身不值得, 就是无稽之谈.
引入一篇很好的译文: juejin.cn/post/693414...
目前 Deno 团队在内部代码中使用 TypeScript 时,遇到的问题有如下这些:
- 当更改文件时,TypeScript 的编译需要几分钟,这使得项目文件的连续编译非常缓慢。
- 在创建实际的 Deno 可执行文件和面向用户的 API 文件时,使用的 TypeScript 结构会造成项目运行的性能问题。
- 事实证明,TypeScript 本身对 Deno 代码管理没有帮助,并且 Deno 团队正经受着相反的效果。在项目的议题列表中就提到一个问题:在两个不同的位置产生了相同的独立主体类。
- 必须手动保持内部代码和运行时 TypeScript 声明的同步,因为 TypeScript 编译器对生成 d.ts 文件没有帮助。
- Deno 团队需要去维护两台 TS 编译器主机:一个用于内部代码,另一个用于外部用户代码,尽管两者的目标相似。
deno的其中一个观点实际上与svelte类似, 都是typescript带来的构建问题. 但deno对于jsdoc的编写却更加彻底, 直接用jsdoc中的@typedef
进行自定义类型声明和类型编程.
至于其它问题, 那都是归结于deno平台自身会遇到的问题, 我们大多数人不会去开发这类平台, 所以不需要太多关注.
下面是deno的源码截图:
3. Turbo8
Turbo8的作者DHH的思想, 我认为是比较偏离大众的, 甚至不能说只放弃了typescript, 而是直接放弃了类型标注和类型提示. 在typescript尚未流行的时候, jsdoc实际上已经有类型标记和类型提示了.
我们在turbo8中, 几乎不能看到jsdoc的存在, 而带类型标注的jsdoc是根本找不到.
没有任何类型标注, DHH是怎么维护turbo8的呢? 带着这个疑问, 我们来看看turbo8的实现:
在turbo8的源码中, 我们能看到大量的面向对象编程. 对于迭代速度相对慢的第三方库来说, 面向对象编程也是一个不错的选择.
但面向对象编程本身就是既能造概念(每个类都是一个概念), 又能提供不错的类型提示(写类确实是这样的), 所以DHH大佬的决定对于Turbo8是比较合理的. 只要有清晰的api文档, Turbo8就是一个很优秀的项目.
但对于我们这些常年迭代公司项目的程序员来说, 往往需要造不少的概念, 甚至一个大模块中就有数个概念, 而在频繁迭代下, 靠大量的面向对象编程或许不太合适, 继承什么的频繁迭代起来太痛苦了, 低副作用的函数式编程或许是一个不错的归宿, 但在大量函数式编程下, 类型标注, 甚至是类型编程, 就变得重要了起来.
typescript源码编程的优势在哪
一方面: 学会并习惯 typescript 甚至是typescript中的严格模式后, 写 jsdoc + .d.ts 能更加得心应手. 而且 .d.ts 本身就属于 typescript
一方面: tsconfig 带来的代码lint能力有利于提升项目的代码质量.
一方面: typescript 代码写起来会更方便, 大量依赖类型声明和类型编程的话, jsdoc + .d.ts 没那么丝滑. 当然还得看个人喜好.
jsdoc组合拳
至于如何用 jsdoc组合拳 进行第三方库的开发, 后续我还会写文章(提前关注我一波), 毕竟是稀文, 不写可惜.
总结
deno和svelte看似放弃了typescript, 实际上是靠其它形式继续使用typescript.
本质就是两个问题的思考:
- 是否应该放弃typescript带来的编译问题
- 是否应该放弃类型标注
在未来浏览器的大力支持下或者社区的支持下(typescript运行时浏览器插件), typescript带来的编译问题或许不再是问题, 这不能算是typescript的错, 只能说环境不造就技术. 至于typescript会提升调试成本和typescript带来的便利, 还需要放在项目上单独抉择. 而对于第三方库的开发来说, 我们的选择可以更倾向于js + jsdoc, 对于项目的开发来说, 我们的选择可以更倾向于typescript. 而是否放弃类型标注, 这才是永恒需要思考的问题.
对于软件工程这个大行业来说, 并没有所谓的银弹, 每些技术的出现都是为了解决某些问题的. 所以在思考一个技术值不值得时, 我们应该把目光聚焦于这些问题身上, 从问题的角度出发, 我们才能够想得更彻底, 更通透, 不至于被社区的节奏带着跑.