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条