是的你可以and你在伪代码中几乎完全正确
interface A {
a?: number;
b?: string;
hasAandB(): this is {a: number} & {b: string};
}
注意你的伪代码是如何的and
成为一个&
。确实非常接近。
当然,没有必要使用该运算符,类型路口运算符,在这种情况下,因为我们可以将其简化为
hasAandB(): this is {a: number, b: string};
但想象一下我们添加第三个属性,比如说c
,它不受类型保护的影响,但我们仍然不想失去它对结果类型的贡献。
您对可组合类型防护的直觉让我们回到原点
hasAandB(): this is this & {a: number, b: string};
您可以使用这些模式做各种非常有趣且非常有用的事情。
例如,您通常可以根据对象的类型传递许多属性键,并且根据您传递的实际键,结果可以针对每个属性的持有者的交集进行类型保护。
function hasProperties<T, K1 extends keyof T, K2 extends keyof T>(
x: Partial<T>,
key1: K1,
key2: K2
): x is Partial<T> & {[P in K1 | K2]: T[P]} {
return key1 in x && key2 in x;
}
interface I {
a: string;
b: number;
c: boolean;
}
declare let x: Partial<I>;
if (hasProperties(x, 'a', 'b')) {...}
事实上,这只是触及了可能性的表面。
另一个非常有趣的应用是定义任意通用和类型安全的构建器和可组合工厂。