近日名为 Evan Martin 的 Google 员工在 TypeScript 的 GitHub repo 中发表了对 TypeScript 的“吐槽”(就是提了一个 issue),用吐槽来表达可能不太合适,准确来说是对 TypeScript 3.5 的使用反馈。
背景
开发团队面对的项目是拥有数十亿行代码的 Google,在团队内部,所有成员使用的是同一版本的 TypeScript 和同一组跨所有平台的编译器标记(compiler flag),如需升级,成员会协助为所有人同时升级这些标记。
Evan 说到,他和大家一样会期望 TypeScript 的新版本升级能带来一些改进。例如,Evan 表示自己希望并欢迎对标准库进行改进,即便这可能意味着需要从代码库中删除类似但不兼容的定义。但团队发现此次升级至 TypeScript 3.5 带来的额外工作量要比此前的升级多得多。
Evan 认为 3.5 版本中有三个主要变化让此次升级变得尤其艰难,他相信这些变化的大多数是有其目标的,并且旨在改进类型检查,但他也认为 TypeScript 团队所理解的类型检查始终只是在安全与效率之间权衡。
为此,Evan 希望这份基于大型代码库的 TypeScript 使用反馈能帮助 TypeScript 团队更好地评估未来类似的情况,并提供一些建议。
下面看看 Evan 说的 3.5 版本给团队带来影响的三个主要变化。
泛型的隐式默认值(Implicit default for generics)
function dontCarePromise() {
return new Promise((resolve) => {
resolve();
});
}
Promise<{}>
的代码在 3.5 中就会变为 Promise<unknown>
。如果此函数的使用者在任意地方写下了这种类型的 Promise:const myPromise: Promise<{}> = dontCarePromise();
这将会导致出现类型错误。
expectsString(myFunction());
const x = myFunction();
expectsString(x);
但最后发现,这是行不通的。
布尔过滤器 filter(Boolean)
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)
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。
开源中国征稿啦!
开源中国 www.oschina.net 是目前备受关注、具有强大影响力的开源技术社区,拥有超过 400 万的开源技术精英。我们传播开源的理念,推广开源项目,为 IT 开发者提供一个发现、使用、并交流开源技术的平台。
现在我们开始对外征稿啦!如果你有优秀的技术文章想要分享,热点的行业资讯需要报道等等,欢迎联系开源中国进行投稿。投稿详情及联系方式请参见:我要投稿
文章评论