Google 员工吐槽 TypeScript:我觉得你的类型检查不太好

局长
 局长
发布于 2019年09月12日
收藏 13

近日名为 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。

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。
转载请注明:文章转载自 OSCHINA 社区 [http://www.oschina.net]
本文标题:Google 员工吐槽 TypeScript:我觉得你的类型检查不太好
加载中

精彩评论

Ricbet
Ricbet
没有了类型才晦涩难懂
egmkang
egmkang
最后

Evan 表示他们对 TypeScript 非常满意,此次的使用反馈只是希望能给团队在设计新特性时提供些许参考,以更好地开发 TypeScript。

香, 真香
志田未来
志田未来
Google不是有Dart嘛
AutoPlus
AutoPlus
Dart 快滚蛋吧
久永
久永
这种叫虚伪!
总是叫别人不要做,不用做,自己努力做。
可以,这很美国。

最新评论(28

kakai
kakai
ts和前几年大火的actionscript3太像了
舌尖跳舞
舌尖跳舞
所以Dart什么鬼
沧海一刀
沧海一刀
我觉得js很js
LeeNux
LeeNux
小项目还是别用ts比较好!虽然我觉得ts很香。
W
WindSpeed
标题党
二进制艺术
二进制艺术
感觉 dart 最像 java
Ning1994
Ning1994
不务正业,不好好写自家的dart
wenxingjun
wenxingjun
写ts时感觉在写JAVA,对于jser来说,很不友好
坐定定
坐定定
ts的大热,是防止团队的成员天马行空,一人一个标准
雷兽
我不是ts的用户 js都很久不怎么用了 一直是强类型的 不是特别懂这方面 随便说说。。。。ts之所以热技术因为强类型检查吧。。。。习惯了弱类型的jser自然觉得别扭吧。。。。。
AutoPlus
AutoPlus
Dart 快滚蛋吧
行者__
行者__
阴阳 不可绝对. 类型是好. 但有时没有更好. . 这方面 clojure 做的优秀. 你想严格点. spec 上起. 你想松点. 就别管类型..
和谐相处.
返回顶部
顶部