2022年3月

在 tsconfig.json 文件中,有一个配置项叫做 strict,默认为 true,表示开启严格模式:

{
    /* Strict Type-Checking Options */
    "strict": true,                       /* Enable all strict type-checking options. */
}

复制代码
TypeScript 中的严格模式跟 JavaScript 中说的严格模式(即 use strict)不是一个概念,它表示是否开启下面一系列的类型检查规则:

{
    "noImplicitAny": true,
    "strictNullChecks": true, 
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitThis": true,
    "alwaysStrict": true
}

意思是说:

如果你设置 strict 为 true 的话,那么上面所有的配置默认全是 true
如果你设置 strict 为 false 的话,那么上面的所有配置默认全是 false
你如果既设置了 strict 又单独设置了其中的部分配置,那么以单独设置的配置为准

知道了这层关系之后,接下来就逐个解释 strict 所关联的配置项分别代表什么含义:

noImplicitAny

不允许出现隐式的 any 类型。下图声明了一个判断奇偶的函数:

TypeScript 是可以进行自动类型推断的,nums 被推断成数字类型的数组,isOddNumber 被推断成返回布尔值的函数,但是参数 num 没有定义类型,TypeScript 只能推断为 any 类型,这就等价于写了下面的代码:

const nums: number[] = [1, 2, 3]
const isOddNumber = (num: any): boolean => (num % 2) !== 0

这样的代码是有 bug 的,例如:

isOddNumber('a') // true
isOddNumber(undefined) // true

建议开启 noImplicitAny 选项。

strictNullChecks

严格空检查。如果关闭此选项,则 null 和 undefined 两种类型是任意类型的子类型,即下面的语法不会报错:

let num: number = 1
let str: string = 'hello'
let student: { name: string; age: number }  = { name: '小明', age: 12}

num = str = student = null
num = str = student = undefined

这样有可能引发未知的结果甚至 runtime error,因为下面的取值或运算都是合法的:

console.log(num + 10) // NaN
console.log(student.age) // TypeError: Cannot read property 'age' of undefined

建议开启 noImplicitAny 选项。

strictFunctionTypes

严格函数类型检查。我们知道,下面的赋值语法在 TypeScript 中是不允许的:

但可笑的是,在不开启 strictFunctionTypes 的情况下,如果你写出下面的代码,TypeScript 竟然是允许的:
function getCurrentYear(callback: (date: string | number) => void) {
callback(Math.random() > 0.5 ? '2020' : 2020)
}
getCurrentYear((date: string) => {
console.log(date.charAt(0))
})
复制代码
真是毫无道理,所以强烈建议开启 strictFunctionTypes 选项。
strictBindCallApply
严格绑定检查。意思是在使用 bind、call 和 apply 语法的时候,是否进行参数检查,如果不开启的话,效果如下:

这明显是不合理的,因为如果通过 call 就能绕过了 TypeScript 的类型检查的话,代码中肯定会出现隐藏的 bug,所以强烈建议开启。
strictPropertyInitialization
严格属性初始化检查。这个选项要和 strictNullChecks 配合使用才行,否则会出现下面的报错:

该选项用于检查类的属性是否被初始化,如果开启则必须进行初始化,否则会出现下面的报错:

解决方法就是:
class User {
name: string = "";
setName(name: string) {

this.name = name;

}
}
复制代码
建议开启 strictPropertyInitialization 选项。
noImplicitThis
不允许出现隐式any类型的this。JavaScript 是一门非常灵活的语言,TypeScript 对于 this 并不能很好地做类型推断,只能推断其为 any 类圆形了,例如像下面这种情况:

这种 any 类型的 this 在理解上是有歧义的,例如:
new Person('小明').say().call({name: '小红'})
// 小明
// hello, my name is 小红
复制代码
建议开启 noImplicitThis 选项。
alwaysStrict
是否开启严格模式。这个不用多说,就是 JavaScript 中的 "use strict",肯定是要开启的。

作者:乔珂力
链接:https://juejin.cn/post/6896680181000634376
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

VLOOKUP(
    找什么,
    在哪找,
    找第几列,
    怎么找(FALSE为精确找)
)

注意:

VLOOKUP有个坑(隐含条件),第1个参数所在列必须在第2个参数范围内的首列,否则N/A


当查找的内容不在第一列时该怎么办?

先用Match返回行号,再用Index返回指定行的内容

MATCH(
    找什么,
    在哪找,
    怎么找(0为精确匹配)
)

INDEX(
    在哪找,
    找第几行(也就是MATCH返回的结果)
)

参考:
[[2017-12-29] vlookup为什么查找目标一定要在该区域的第一列?](https://zhidao.baidu.com/question/1964314264236411140.html "vlookup为什么查找目标一定要在该区域的第一列?")
[[2020-07-14] Excel里VLOOKUP只能查找第一列,想查找表格的其他列该怎么办?](http://www.360doc.com/content/20/0714/07/68414255_924119422.shtml "Excel里VLOOKUP只能查找第一列,想查找表格的其他列该怎么办?")