故事是从Google团队升级了TypeScript的版本至3.5后开始的:
1、泛型的隐式默认值(Implicit default for generics)
这是3.5版本升级后破坏性的主要变化
主要异常表现:代码中使用到泛型,但是代码并不关注泛型做了什么。
下面是一个🌰
1 | // i.e 下面的Promise中resolve返回一个值,但是Promise本身并不关注这个值是什么 |
在3.4版本及以下,泛型是宽松的,这里的Promise实际是Promise<{}>,然而在3.5中被解释成Promise
那么问题来了,如果有个人在自己的项目中大量写了下面的代码:
1 | const myPromise: Promise<{}> = dontCarePromise() |
就造成了对使用者没有任何益处的类型报错,此次版本升级中关于泛型的改变所带来的缺失就和上述现象相似。
比如d3的类型声明库中有一个非常复杂的类型d3.Selection<>,使用时需要传入4个泛型参数来明确这个泛型类型,i.e
1 | mySel: d3.Selection<HTMLElement, {}, null, undefined> |
然而在3.5版本中,第二个参数类型{}会变成unknown
主要的结论是d3的类型声明是不那么完美的,使用时需要加以注意,不过这是和此次升级无关的。
还有一种异常表现是在只将泛型作为返回值的依赖注入模式中,来看一下下面的代码:
1 | function getService<T>(service: Ctor<T>): T |
当Ctor是某种匹配Class类型时,主要使用场景是以下代码:
1 | class MyService {...} |