在 printAll 函数中,我们尝试检查 strs 是否为对象以查看它是否为数组类型(现在可能是强调数组是 JavaScript 中的对象类型的好时机)。 但事实证明,在 JavaScript 中,typeof null 实际上是“object”! 这是历史上的不幸事故之一。
有足够经验的用户可能不会感到惊讶,但并不是每个人都在 JavaScript 中遇到过这种情况; 幸运的是,TypeScript 让我们知道 strs 只缩小到 string[] | null 而不仅仅是 string[]。
这可能是我们所谓的“真实性”检查的一个很好的过渡。
Truthiness narrowing
// both of these result in 'true'
Boolean("hello"); // type: boolean, value: true
!!"world"; // type: true, value: true
1
2
3
双感叹号是 Boolean 函数调用的简写形式。
因此上面的代码可以修改成:
function printAll(strs: string | string[] | null) {
if (strs && typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
} else {
// do nothing
}
}
1
2
3
4
5
6
7
8
9
10
11
使用 in 关键字进行的 narrowing
Javascript 有一个运算符来确定对象是否具有带名称的属性:in 运算符。 TypeScript 将这一点作为缩小潜在类型的一种方式。
例如,使用代码:x 中的“值”。 其中“value”是字符串文字,x 是联合类型。 “true”分支缩小了具有可选或必需属性值的 x 类型,“false”分支缩小到具有可选或缺失属性值的类型。
例子:
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
if ("swim" in animal) {
return animal.swim();
}
return animal.fly();
}