typescript 给 javascript 扩展了类型的语法和语义,让 js 代码达到了静态类型语言级别的类型安全,之前只能在运行时发现的类型不安全的问题,现在能在编译期间发现了,所以大项目越来越多的选择用 typescript 来写。除此之外,typescript 还能够配合 ide 做更好的智能提示,这也是用 typescript 的一个理由。
类型安全:如果一个类型的变量赋值给它不兼容类型的值,这就是类型不安全,如果一个类型的对象,调用了它没有的方法,这也是类型不安全。反之,就是类型安全。类型安全就是变量的赋值、对象的函数调用都是在类型支持的范围内。
最开始 typescript 代码只有自带的 tyepscript compiler(tsc)能编译,编译不同版本的 typescript 代码需要用不同版本的 tsc,通过配置 tsconfig.json 来指定如何编译。
但是 tsc 编译 ts 代码为 js 是有问题的:
tsc 不支持很多还在草案阶段的语法,这些语法都是通过 babel 插件来支持的,所以很多项目的工具链是用 tsc 编译一遍 ts 代码,之后再由 babel 编译一遍。这样编译链路长,而且生成的代码也不够精简。
所以,typescript 找 babel 团队合作,在 babel7 中支持了 typescript 的编译,可以通过插件来指定 ts 语法的编译。比如 api 中是这样用:
const parser = require('@babel/parser');
parser.parse(sourceCode, {
plugins: ['typescript']
});
这个插件是 typescript 团队与 babel 团队合作了一年的成果。
但是,这个插件真的能支持所有 typescript 代码么?答案是否定的。
我们来看一下 babel 不支持哪些 ts 语法,为什么不支持。
babel 的编译流程是这样的:
而 typescript compiler 的编译流程是这样的:
其实 babel 的编译阶段和 tsc 的编译阶段是类似的,只是 tsc 多了一个 checker,其余的部分没什么区别。
那么能不能基于 babel 的插件在 traverse 的时候实现 checker 呢?
答案是不可以。
因为 tsc 的类型检查是需要拿到整个工程的类型信息,需要做类型的引入、多个文件的 namespace、enum、interface 等的合并,而 babel 是单个文件编译的,不会解析其他文件的信息。所以做不到和 tsc 一样的类型检查。
一个是在编译过程中解析多个文件,一个是编译过程只针对单个文件,流程上的不同,导致 babel 无法做 tsc 的类型检查。
那么 babel 是怎么编译 typescript 的呢?
其实 babel 只是能够 parse ts 代码成 ast,不会做类型检查,会直接把类型信息去掉,然后打印成目标代码。
这导致了有一些 ts 语法是 babel 所不支持的:
上面两种两个是因为编译方式的不同导致的不支持。
这四种就是 babel 不支持的 ts 语法,其实影响并不大,这几个特性不用就好了。
结论:babel 不能编译所有 typescript 代码,但是除了 namespace 的两个特性外,其余的都可以做编译。
babel 是可以编译 typescript 代码,那么为什么要用 babel 编译呢?
babel 编译 typescript 代码有 3 个主要的优点:
tsc 如何配置编译目标呢?
在 compilerOptions 里面配置 target,target 设置目标语言版本
{
compilerOptions: {
target: "es5" // es3、es2015
}
}
typescript 如何引入 polyfill 呢?
在入口文件里面引入 core-js.
import 'core-js';
babel7 是如何配置编译目标呢?
在 preset-env 里面指定 targets,直接指定目标运行环境(浏览器、node)版本,或者指定 query 字符串,由 browserslist 查出具体的版本。
{
presets: [
[
"@babel/preset-env",
{
targets: {
chrome: 45
}
}
]
]
}
{
presets: [
[
"@babel/preset-env",
{
targets: "last 1 version,> 1%,not dead"
}
]
]
}
babel7 如何引入 polyfill 呢?
也是在 @babel/preset-env 里面配置,除了指定 targets 之外,还要指定 polyfill 用哪个(corejs2 还是 corejs3),如何引入(entry 在入口引入 ,usage 每个模块单独引入用到的)。
{
presets: [
[
"@babel/preset-env",
{
targets: "last 1 version,> 1%,not dead",
corejs: 3,
useBuiltIns: 'usage'
}
]
]
}
这样可以根据 @babel/compat-data 的数据来针对的做语法转换和 api 的 polyfill:
先根据 targets 查出支持的目标环境的版本,再根据目标环境的版本来从所有特性中过滤支持的,剩下的就是不支持的特性。只对这些特性做转换和 polyfill 即可。
而且 babel 还可以通过 @babel/plugin-transform-runtime 来把全局的 corejs 的 import 转成模块化引入的方式。
显然,用 babel 编译 typescript 从产物上看有两个优点:
从产物来看,babel 胜。
typescript 默认支持很多 es 的特性,但是不支持还在草案阶段的特性,babel 的 preset-env 支持所有标准特性,还可以通过 proposal 来支持更多还未进入标准的特性。
{
plugins: ['@babel/proposal-xxx'],
presets: ['@babel/presets-env', {...}]
}
从支持的语言特性来看,babel 胜。
tsc 会在编译过程中进行类型检查,类型检查需要综合多个文件的类型信息,要对 AST 做类型推导,比较耗时,而 babel 不做类型检查,所以编译速度会快很多。
从编译速度来看, babel 胜。
总之,从编译产物大小(主要)、支持的语言特性、编译速度来看,babel 完胜。
但是,babel 不做类型检查,那怎么类型检查呢?
babel 可以编译生成更小的产物,有更快的编译速度和更多的特性支持,所以我们选择用 babel 编译 typescript 代码。但是类型检查也是需要的,可以在 npm scripts 中配一个命令:
{
"scripts": {
"typeCheck": "tsc --noEmit"
}
}
这样在需要进行类型检查的时候单独执行一下 npm run typeCheck 就行了,但最好在 git commit 的 hook 里(通过 husky 配置)再执行一次强制的类型检查。
typescript 给 js 扩展了静态类型的支持,使得代码能够在编译期间检查出赋值类型不匹配、调用了没有的方法等错误,保证类型安全。
除了 tsc 之外,babel7 也能编译 typescript 代码了,这是两个团队合作一年的结果。
但是 babel 因为单文件编译的特点,做不了和 tsc 的多文件类型编译一样的效果,有几个特性不支持(主要是 namespace 的跨文件合并、导出非 const 的值),不过影响不大,整体是可用的。
babel 做代码编译,还是需要用 tsc 来进行类型检查,单独执行 tsc --noEmit 即可。
babel 编译 ts 代码,相比 tsc 有很多优点:产物体积更小,支持更多特性,编译速度更快。所以用 babel 编译 typescript 是一个更好的选择。
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/Yeg3kJ_uDBzHFwNHD02i9A
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。