在 tsconfig.json 文件中,有一个配置项叫做 strict
,默认为 true,表示开启严格模式:
1 | { |
TypeScript 中的严格模式跟 JavaScript 中说的严格模式(即 use strict
)不是一个概念,它表示是否开启下面一系列的类型检查规则:
1 | { |
意思是说:
- 如果你设置
strict
为 true 的话,那么上面所有的配置默认全是 true - 如果你设置
strict
为 false 的话,那么上面的所有配置默认全是 false - 你如果既设置了
strict
又单独设置了其中的部分配置,那么以单独设置的配置为准
知道了这层关系之后,接下来就逐个解释 strict
所关联的配置项分别代表什么含义:
noImplicitAny
不允许出现隐式的 any 类型。下图声明了一个判断奇偶的函数:
TypeScript 是可以进行自动类型推断的,nums 被推断成数字类型的数组,isOddNumber 被推断成返回布尔值的函数,但是参数 num 没有定义类型,TypeScript 只能推断为 any 类型,这就等价于写了下面的代码:
1 | const nums: number[] = [1, 2, 3] |
这样的代码是有 bug 的,例如:
1 | isOddNumber('a') // true |
建议开启 noImplicitAny 选项。
strictNullChecks
严格空检查。如果关闭此选项,则 null 和 undefined 两种类型是任意类型的子类型,即下面的语法不会报错:
1 | let num: number = 1 |
这样有可能引发未知的结果甚至 runtime error,因为下面的取值或运算都是合法的:
1 | console.log(num + 10) // NaN |
建议开启 noImplicitAny 选项。
strictFunctionTypes
严格函数类型检查。我们知道,下面的赋值语法在 TypeScript 中是不允许的:
但可笑的是,在不开启 strictFunctionTypes 的情况下,如果你写出下面的代码,TypeScript 竟然是允许的:
1 | function getCurrentYear(callback: (date: string | number) => void) { |
真是毫无道理,所以强烈建议开启 strictFunctionTypes 选项。
strictBindCallApply
严格绑定检查。意思是在使用 bind、call 和 apply 语法的时候,是否进行参数检查,如果不开启的话,效果如下:
这明显是不合理的,因为如果通过 call 就能绕过了 TypeScript 的类型检查的话,代码中肯定会出现隐藏的 bug,所以强烈建议开启。
strictPropertyInitialization
严格属性初始化检查。这个选项要和 strictNullChecks 配合使用才行,否则会出现下面的报错:
用于检查类的属性是否被初始化了,如果开启则必须进行初始化,否则会出现下面的报错:
解决方法就是:
1 | class User { |
建议开启 strictPropertyInitialization 选项。
noImplicitThis
不允许出现隐式any类型的this。JavaScript 是一门非常灵活的语言,TypeScript 对于 this 并不能很好地做类型推断,只能推断其为 any 类圆形了,例如像下面这种情况:
这种 any 类型的 this 在理解上是有歧义的,例如:
1 | new Person('小明').say().call({name: '小红'}) |
建议开启 noImplicitThis 选项。
alwaysStrict
是否开启严格模式。这个不用多说,就是 JavaScript 中的 "use strict"
,肯定是要开启的。