社区精选 |原生JS以后也支持类型注解啦?

业界 作者:SegmentFault 2022-07-11 14:13:25

今天为各位小伙伴推荐的是社区作者 卡颂 的文章,在这篇文章中他对原生JS支持类型注解表达了一些看法,让我们看看他是怎么说的吧~




大家好,我卡颂。


在布达佩斯2022 JSConf会议上,tc39(ES标准委员会)成员Gil Tayar介绍了一份当前仍处于stage 1阶段的提案 —— Type Annotations,意在让原生JS支持类型注解。


会议链接:https://www.youtube.com/watch


换句话说,如果提案通过,很多.ts文件将后缀改为.js后就能直接在浏览器中运行。


一份tc39提案通常会经历5个阶段:


  • stage 0:被提出

  • stage 1:接受审议

  • stage 2:规范基本完成

  • stage 3:等待被实现

  • stage 4:纳入语言标准中


所以Type Annotations当前仍处于接受审议的状态。


但是提案发起者Gil Tayar对这份提案的通过很有信心,本文我们来聊聊这份提案的相关内容。


为什么需要原生类型注解?



根据20年、21年state of JS的统计,静态类型高票当选JS中当前最欠缺的功能


统计链接:https://stateofjs.com/en-us/

·


同时,在Github报告中,TS被列为第四大最常用的语


报告链接:https://octoverse.github.com/


所以,对前端工程师来说,类型注解需求很大。


那么,既然已经有了TS,为什么还需要原生JS支持类型注解呢?、


通常来说,从开发者编写的源代码到线上生产环境代码间需要经过代码编译。、


代码编译主要包括两个步骤:


  1. 降级编译(包括高级语法转换为低级语法,高级方法的polyfill)

  2. 代码转译(比如压缩、混淆、tree-shaking、类型擦除)


所谓类型擦除,是指擦除代码中的类型注解,让其变成符合原生JS规范的代码,比如:


// 擦除前
function add(a: number, b: number): number {
  return a + b;
}
// 擦除后
function add(a, b) {
  return a + b;
}


随着时间的推移,各主流浏览器兼容性越来越好,步骤1在可预见的未来重要性会逐渐降低。


对于TS开发者,从源代码线上生产环境代码间可能只需要类型擦除


如果原生JS支持类型注解,就能省去类型擦除对应的编译流程,让代码更容易在宿主环境执行。


和TS的关系



这份提案的目的,并不是另起炉灶,独立实现一套原生JS的类型注解。而是与TS团队合作,提出一套合适的规范。


新的规范与TS规范的关系类似下图:



一方面,Type Annotations提案从TS中借鉴了很多特性,这就是图中相交的部分。


你可以到grammar-conventions看到规范当前定义的类型


链接:

https://tc39.es/proposal-type-annotations/grammar.html#grammar-conventions


另一方面,TS迭代速度很快,新的特性产出很快。而Type Annotations作为JS语言的一部分,迭代会更加保守,所以TS中一些特性在Type Annotations中并不支持。


此外,TS中一些结构(比如Enums、Namespaces)存在运行时的语义,Type Annotations也不会支持。


这些就是TS中存在,而Type Annotations中不存在的部分。


最后,Type Annotations设计的初衷并不是与TS强绑定,而仅仅是提供一套类型规范,开发者编写代码时的类型检查还是由各种类型检查器(比如TS、Flow)实现。


所以,Type Annotations还有一部分特性是TS当前未定义的,这也是为了规范更广泛的适用性考虑的,也就是图中Type Annotations存在,而TS不存在的部分。


这部分特性需要TS后续实现,这也是为什么Type Annotations要与TS团队合作的一大原因。


对开发者意味着什么



如果Type Annotations最终出现在ES20xx版中,届时开发者编写代码的步骤是:


  1. 选择合适的类型检查器(比如TS),这个类型检查器需要完全遵循TypeAnnotations规范(而不是自己的规范,比如TS规范)

  2. 编写带类型声明的原生JS代码

  3. 类型检查器会检查类型错误,并给予报错或提示


对于如下原生JS代码,如果开发者传入了错误的类型,JS会报错么?


function add(a: number, b: number): number {
  return a + b;
}

// 错误的类型传参
add('KaSong', 123);


答案是:不会。


Type Annotations仅仅是一套规范,该规范由各种类型检查器执行。


JS的宿主环境(比如浏览器)在执行带类型声明的JS代码时,会忽略类型声明。


总结



有同学可能会问:就为了减少编译时类型擦除这一步,就提出原生类型规范,有必要么?


甚至当Type Annotations落地后,开发者上线前在进行代码压缩时,类型擦除也会作为代码压缩的职责之一。


从这个角度看,甚至没有减少编译时的工作量。


所以提出原生的类型规范,有必要么?


前端的发展实际是一个努力去编译时流程的过程。


比如,编译时代码需要降级,需要polyfill?随着IE11停止服务,主流浏览器纷纷跟进标准落地,降级与polyfill的需求逐渐变少。


再比如,代码需要打包?随着ESM规范落地,在当前,至少在开发环境中代码已经不需要打包(使用Vite)。


Type Annotations的出现,就是遵循努力去编译时流程这一趋势的产物。

从这个角度看,还是很有必要的。




SegmentFault 思否社区小编说


自 2022-07-01 起 SegmentFault 思否公众号改版啦!之后将陆续推出新的栏目和大家见面!(请拭目以待呀~


在「社区精选」栏目中,我们将为广大开发者推荐来自 SegmentFault 思否开发者社区的优质技术文章,这些文章全部出自社区中充满智慧的技术创作者哦!


希望通过这一栏目,大家可以共同学习技术干货,GET 新技能和各种花式技术小 Tips。


欢迎越来越多的开发者加入创作者的行列,我们将持续甄选出社区中优质的内容推介给更多人,让闪闪发光的技术创作者们走到聚光灯下,被更多人认识。


「社区精选」投稿邮箱:pr@segmentfault.com

投稿请附上社区文章地址





点击左下角阅读原文,到 SegmentFault 思否社区 和文章作者展开更多互动和交流,公众号后台回复“ 入群 ”即可加入我们的技术交流群,收获更多的技术文章~

- END -


关注公众号:拾黑(shiheibook)了解更多

赞助链接:

关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接