TypeScript - 在什么时候会需要使用 'is' 谓词,而不是使用 'in' 操作符?
根据 TypeScript 文档,我们可以使用类型保护来区分不同的类型。
文档给出了使用 is 谓词和使用 in 操作符的示例。
是 谓词:
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
if (isFish(pet)) {
pet.swim();
}
else {
pet.fly();
}
in 操作符:
function move(pet: Fish | Bird) {
if ("swim" in pet) {
return pet.swim();
}
return pet.fly();
}
in 运算符看起来要简洁得多,也更简单——尽管也许将类型区分明确地提取到一个函数中是有帮助的,而且从长期来看更易于维护。
是否存在某些情况下 is 谓词可以区分类型,而 in 运算符不能?
答案 #1
in 操作符只是缩小变量类型的一种方法。你可以使用任何你喜欢的检查来编写类型保护:
type JSONPrimitive = number | string | boolean | null;
function isJsonPrimitive(x: any): x is JSONPrimitive {
return x === null
|| typeof x === 'number'
|| typeof x === 'string'
|| typeof x === 'boolean';
}
或者:
interface TreeNode {
value: number;
left: TreeNode | null;
right: TreeNode | null;
}
type InternalNode = TreeNode & ({ left: TreeNode } | { right: TreeNode });
function isInternalNode(node: TreeNode): node is InternalNode {
return node.left !== null || node.right !== null;
}
这两个例子都不能用 in 运算符进行等效重写。
也就是说,用户定义的类型保护类似于类型断言,因为 TypeScript 不会检查它们的正确性。所以你可以在类型保护的实现中使用任何你喜欢的逻辑;甚至无条件的 return true; 也是允许的。
