[译]2022年应该戒掉的10个TypeScript坏习惯

4,919 阅读6分钟

TypeScript和JavaScript在过去几年不断的增强升级,我们在过去十年建立起来的最佳实践可能已经有些过时了,有些也失去了意义,下面列出10个我们都应该戒掉的坏习惯。

1.不使用严格模式(strict modal

例子:

tscofig.json中没有strict声明

应该怎么做

为什么会这样做

在代码中使用严格模式通常会带来更多的时间成本

为什么我们不应该这样做

严格的规则能减少将来我们修改代码的成本,因此编码时带来的时间成本在我们迭代升级的时候可以节省出来。

2.使用||定义默认值

例子:

使用双竖线来指定默认值

应该怎么做

使用TypeScript的空值合并操作符?? 或者更好的: 在参数上定义默认值

为什么会这样做

??操作符是在去年引入的,如果在复杂函数中间使用变量,很难在在参数的时候就赋默认值。

为什么我们不应该使用||

??不像||,他仅仅在左侧是null或者undefined的时候生效,并不匹配falsy的值(0就是falsy value),此外,如果你的复杂方法不能在开始的时候定义默认值,那么使用它是个不错的选择。

3.使用any类型

例子:

在不知道数据结构的时候使用any类型

应该怎么做

绝大多数使用any类型的场景,我们应当使用unkown来代替any。

为什么会这么做

any是基本类型,使用any时ts不会做类型检查,any也经常被用于官方类型中(例如:上面例子中的response.json()类型被TypeScript团队定义为Promise<any>类型)

为什么不使用any

ts不会对any类型做类型检查,任何对any类型值的变更也不会被检查,这时候定位问题变得很困难(就和js 运行一样),只有当运行时的赋值和预期的一致的时候才不会出错。

4. 直接使用as做类型转换

例子:

当编译器不能推断的时候告知编译器类型

应当怎么做

为as做一个前置守卫,例如(ps:注意 is的使用方法):

为什么会这样做

当我们把JavaScript转换成TypeScript时, 现有的代码库经常没有针对TypeScript做出类型定义,在这些场景, 使用as可以快速的完成类型转换。

为什么我们不应该

直接使用as虽然让代码可以正常运行,但是当有人改动代码造成结构体发生变化时,有一个前置守卫可以保证变更的代码仍然是符合预期的

5.在测试用例中使用as any

例子:

当编写一个数据不完整的测试用例时

应该怎么做?

如果你需要在测试用例里mock数据, 那么将mock方法放在你测试逻辑的上方并且确保可以复用。

为什么会这样做

刚开始编写测试代码的时候还没有很大的测试覆盖度,但是经常会有复杂的大的数据结构,而我们在测试的时候只有部分属性是测试代码所必需的。短时间内,不关心别的属性是更简单的。

为什么我们不应该

上面不正确的方法可能会导致代码维护或者迭代上得困难,比如当一个属性发生变化时,我们必须更改所有测试用例中用到的地方而不是一个中心化的位置,另外,如果一个测试依赖于我们之前认为不重要的属性,那么我们就必须更改所有的测试用例

6.可选属性

例子:

将具有内部逻辑关系的属性定义为可选属性

应该怎么做

清晰的表达内部逻辑关系,如果是digital则应该存在sizeInMb属性,如果是physical则应该存在weightInKg属性

为什么会这么做

将属性定义为可选比分割代码更容易,代码量也更少,如果需求发生变化,它也 可以很方便的修改。

为什么不应该这样做

类型系统的最大好处是它们可以用编译时检查代替运行时检查。使用更合理的类型,可以在编译时检查可能会被忽视的错误,例如通过确保每个 DigitalProduct 都有一个 sizeInMb。

7.使用一个字母的泛型

例子:

应该怎么做

应该用一个完整语义的名称来定义泛型

为什么会这样做

我想这个习惯会很容易养成,毕竟官方文档都是用T来表达类型,而且这样写更简单也不用过多考虑其他。

为什么不应该这样做

通常泛型类型变量也是变量,就像其他变量一样。一个字母的变量名称通常会让人感到奇怪,因为如果不查看定义声明,可能很难知道它们的具体含义。

8.使用非布尔型来做布尔判断

例子

在if中直接使用非布尔型变量校验变量是否定义

应该怎么做

我们需要明确的检测变量

什么会有这个习惯

这样写往往更简单和直接,并且减少了我们关于变量具体值的思考量

为什么不应该这样做

也许我们应该仔细思考我们真正想校验什么?上面两个例子很好的演示了当countOfNewMessages为0时的不同

9.使用!!操作

例子:

转换非布尔型值为布尔型

应该怎么做

我们应该清晰的知道校验条件(一些老开发可能会习惯用他)

为什么会这样做

对我们中的一些人来说,理解!!就像是开启了 JavaScript 世界的一个仪式。它看起来简短明了,如果你已经熟悉它,那么你就知道它是做什么的:这是将任何值转换为布尔值的简短方法。特别是在代码库中,虚值(如 null、 undefined 和'')之间没有明确的语义分割的情况下。

为什么不这样做

!!就像魔法一样掩盖了变量的真实含义,这对于一个新人或者一个js新手来说是难以理解的,同样的,他也会导致一些bug,比如这个countOfNewMessages为0的情况

备注:原文只有9条,所以就只能翻译9条

原文:medium.com/@imranfaroo…