【问题标题】:Why should i use a predicate as a return type instead of a boolean?为什么我应该使用谓词作为返回类型而不是布尔值?
【发布时间】:2018-09-12 02:52:37
【问题描述】:

我在阅读这篇文章时发现了用户定义的类型保护:https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards

在本文的一个示例中,他们使用pet is Fish 作为方法返回类型,即谓词。

我发现除了这种返回类型,也可以使用boolean。那么parameter is Type 返回类型只是语法糖还是有特定用途?

【问题讨论】:

  • 具体使用在链接中有说明。如果您对未知类型的变量进行类型检查并且结果为 true,则 typescript 知道该变量是一条鱼,您可以安全地对待它。

标签: angular typescript


【解决方案1】:

如果您返回boolean,该函数将是一个不是类型保护的简单函数。 pet is Fish 语法向编译器发出信号,表明此函数将影响参数的类型。

例如:

class Fish { f: boolean }
class Dog { d: boolean; }

declare let x: Fish | Dog;
declare function isFish(p: Fish | Dog): boolean
declare function isFishGuard(p: Fish | Dog): p is Fish;

if (isFishGuard(x)) {
    x.f // x is Fish
}

if (isFish(x)) {
    x.f // error x is still Fish|Dog
}

Playground link

【讨论】:

  • 为什么第二个if给你一个错误?我注意到,当您将变量声明为 type1 | type2 时,该变量会同时获得 type1 和 type2 的属性,这意味着在通过类型保护确定实际类型后,无需将变量转换为两种类型中的任何一种.因此,如果 x 的实际类型不是鱼,则第二个 if 中的 x.f 只会返回值 undefined
  • @Maurice type1 | type2 是联合类型,这意味着它可以是 type1type2。 Typescript 只会让您访问此类类型的公共属性(在这种情况下,没有公共属性)。 type1 & type2 是一个交集类型,将允许访问这两种类型的属性。类型保护旨在将联合类型(在本例中为 Fish | Dog)缩小为更具体的内容(在本例中,isFishGuard 会将 x 的类型缩小为 Fish
  • 请查看我在EDIT: 下发布的代码sn-p。这运行没有错误。 AdvancedFilter 和 HTMLInputElement 都没有一个名为 value 的属性,只有 HTMLInputElement 有这个属性,但在 else 部分我仍然可以调用 filter.value 而不必先将 filter 转换为 HTMLInputElement
  • @Maurice 没有isAdvancedFilterAdvancedFilter 的定义,很难判断发生了什么。您可以在操场上尝试我的示例,您将在第二次访问时遇到错误。我会在答案中添加一个游乐场链接。
  • 没关系,我已经从帖子中删除了编辑,因为你是对的。虽然AdvancedFilter 类没有声明value 成员,但该类确实继承了超类object/any 的所有成员。该类确实有一个 value 成员,这解释了为什么在使用该成员而不首先转换为 HTMLInputElement 时我没有遇到运行时错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 2013-01-03
  • 2015-02-19
  • 2020-03-21
  • 2011-06-19
相关资源
最近更新 更多