是否可以将TypeScript类型谓词分配给变量

时间:2019-12-02 16:56:30

标签: typescript typeguards

考虑来自TypeScript docs的此类谓词:

e = M x 1

我有一些这样的代码:

function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

我希望通过将结果分配给变量然后进行检查来避免两次调用function inRightPlace(pet: Fish | Bird) { return ( (isFish(pet) && pet.inWater()) || (!isFish(pet) && pet.inSky()) ); 。像这样:

isFish

不过,TypeScript编译器不喜欢这样,因为对function inRightPlace(pet: Fish | Bird) { const isAFish = isFish(pet); return ( (isAFish && pet.inWater()) || (!isAFish && pet.inSky()) ); 的检查不能作为对isAFish类型的公认测试。我曾尝试给pet提供isAFish(pet is Fish)类型,但看起来类型谓词不能用作此类变量的类型。

给我的印象是,这里无法避免对类型保护函数的重复调用,但是我在网上找不到太多,因此希望以任何一种方式进行确认。

1 个答案:

答案 0 :(得分:2)

否,您不能将用户定义的类型防护的结果分配给变量并以相同的方式使用它。之前曾建议过这种功能:请参见microsoft/TypeScript#24865和/或microsoft/TypeScript#12184。如果您对此很在意,可以去那里给它?。

但是,对于您的特定示例,我建议使用ternary operator(x && y) || (!x && z)替换为x ? y : z(如果x ? (y || false) : z不同,也可以使用y || false y足以满足您的需求)。这只会评估您的用户定义类型防护一次,并且编译器对三元运算符了解足够多,可以缩小控制流:

function inRightPlace(pet: Fish | Bird) {
    return isFish(pet) ? (pet.inWater() || false) : pet.inSky(); // okay
}

好的,希望能有所帮助;祝你好运!

Link to code