Google 员工吐槽 TypeScript:我觉得你的类型检查不太好
近日名为 Evan Martin 的 Google 员工在 TypeScript 的 GitHub repo 中发表了对 TypeScript 的“吐槽”(就是提了一个 issue),说吐槽可能不太合适,准确来说是对 TypeScript 3.5 的使用反馈。
虽然 TypeScript 3.5 发布已有三个月(最新稳定版 3.6 已于上月月底发布),但 Google 开发团队最近才升级至 3.5 版本。使用一段时间后,开发者觉得不吐不快,于是便有了这篇质量颇高的使用反馈。是的,这里说的项目正是被众人使用的 Google —— 那个只有一个代码仓库且拥有数十亿行代码的 Google。
背景
开发团队面对的项目是拥有数十亿行代码的 Google,在团队内部,所有成员使用的是同一版本的 TypeScript 和同一组跨所有平台的编译器标记(compiler flag),如需升级,成员会协助为所有人同时升级这些标记。
Evan 说到,他和大家一样会期望 TypeScript 的新版本升级能带来一些改进。例如,Evan 表示自己希望并欢迎对标准库进行改进,即便这可能意味着需要从代码库中删除类似但不兼容的定义。但团队发现此次升级至 TypeScript 3.5 带来的额外工作量要比此前的升级多得多。
Evan 认为 3.5 版本中有三个主要变化让此次升级变得尤其艰难,他相信这些变化的大多数是有其目标的,并且旨在改进类型检查,但他也认为 TypeScript 团队所理解的类型检查始终只是在安全与效率之间权衡。
Evan 希望这份大型代码库的 TypeScript 使用反馈能帮助 TypeScript 团队更好地评估未来类似的情况,并提供一些建议。
下面看看 Evan 说的 3.5 版本给团队带来影响的三个主要变化。
泛型的隐式默认值(Implicit default for generics)
此项特性属于 3.5 版本中的破坏性变化,Evan 认为这里导致出现问题的原因是代码的泛型与代码所做的工作并无相关。例如,假设有一些具有 Promise 解析的代码,但不关心 Promise 要解析的值:
function dontCarePromise() { return new Promise((resolve) => { resolve(); }); }
由于泛型是未绑定的,在 3.4 中为 Promise<{}>
的代码在 3.5 中就会变为 Promise<unknown>
。如果此函数的使用者在任意地方写下了这种类型的 Promise:
const myPromise: Promise<{}> = dontCarePromise();
这将会导致出现类型错误。
除此之外,还有一种被称为“仅返回泛型(return-only generics)”的模式,这种情况下,泛型函数仅在返回类型中使用它的任意模式。这里导致的问题是,会出现很多类型推导意外。例如,在只返回泛型的情况下,有如下的代码:
expectsString(myFunction());
可以按以下的方式合法重构:
const x = myFunction(); expectsString(x);
但最后发现,这是行不通的。
布尔过滤器 filter(Boolean)
TypeScript 3.5 更改了Boolean
函数的类型,该函数会强制赋值给boolean
,从
function Boolean(value?: any): boolean;
变为
function Boolean<T>(value?: T): boolean;
两者看起来可能非常相似。但试想一下,一个函数接受了一个谓词并返回一个数组过滤器,并像上面的代码一样使用:
function filter<T>(predicate: (t: T) => boolean): (ts: T[]) => T[]; const myFilter = filter(Boolean);
在 3.4 版本中,根据定义,T
从 any
变为myFilter
,并成为一个由 any[]
到 any[]
的函数。但在 3.5 版本中,T
只保留了泛型。
集合(Set)
在 TypeScript 3.4 中,下面的代码:
const s = new Set();
会返回一个 Set<any>
。但 TypeScript 3.5 出现了一个变更,使得 lib.es2015.iterable.d.ts
具有移除 any
的效果,然后导致泛型改变上面的描述,并将类型推导为 unknown
。
这种变化最终很难修复,因为最终的类型错误有时与实际问题相差甚远。例如,在如下代码中:
class C { gather() { let s = new Set(); s.add('hello'); return s; } use(s: string[]) { … } demo() { this.use(Array.from(this.gather())); } }
我们会收到关于 Array.from
类型错误的提示,但实际需要修复的是 new Set()
。
最后
Evan 表示他们对 TypeScript 非常满意,此次的使用反馈只是希望能给团队在设计新特性时提供些许参考,以更好地开发 TypeScript。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
每日一博 | 不要小看小小的 emoji 表情
前言 好久没更新了,最近事比较多,或许下个月就会恢复到正常的发文频次。 这篇文章得从一个 emoji 表情开始,我之前开源的一个 IM 项目中有朋友提到希望可以支持 emoji 表情传输。 https://github.com/crossoverJie/cim/issues/12 正好那段时间有空,加上这功能看着也比较简单准备把它实现了。 <!--more--> 但在真正实现时却发现没那么简单。 我首先尝试将一个 emoji 表情存入数据库看看: 果不其然的出错了,导致这个异常的原因是目前数据库所支持的编码中并不能存放 emoji,那 emoji 表情到底是个什么东西呢。 本质上来说计算机所存储的信息都是二进制 01,emoji 也不例外,只要存储和读取(编解码)的方式一致那就可以准确的展示这个信息。 更多编解码的内容后文再介绍,这里先想想如何快速解决问题。 存储 emoji 虽说想要在 MySQL 中存储 emoji 的方式也有好几种,比如可以升级存储字符集到可以存放 emoji ,但这种需要 MySQL 的版本支持。 所以更保险的方式还是在应用层解决,比如我们是否可以将...
- 下一篇
开发者简报:Stack Overflow 三大定律
微信阅读 Android 10发布 Android 10 支持深色主题、折叠屏、手势导航以及更加注重隐私安全。今后还可以在Google Play获取最新的重要系统更新。不在再需要等设备厂商提供全量系统更新,就可以在运行 Android 10 或更高版本的设备上直接更新特定的系统组件。 到底什么是AndroidX 说得简单直白点就是Support Library API升级版。 全球最大同性交友平台的“黑历史” 标题有些夸张,主要通过漫画形式简述git历史。 GitHub上标星1.5w,flv.js开源作者月薪还不到5k B站三年前开源的flv.js项目大火,标星超过1.5万,但是项目的开源作者谦谦(网名)被曝月薪竟然还不足5000?你觉得你的薪资和你的经验成正比吗? 新闻摘要 Microsoft 365黑暗模式 Outlook为iOS 13和Android Q操作系统适配了黑暗模式 文摘 让下划线更美观 Butterick的“实用排版”中的建议清楚地表明: 如果您有强调下划线的冲动,请使用粗体或斜体。 许多受欢迎的网站都放弃了下划线包括纽约时报,纽约杂志,华盛顿邮报,彭博社,亚马逊,苹...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8编译安装MySQL8.0.19
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7