【问题标题】:user defined type guards [typescript]用户定义的类型保护 [typescript]
【发布时间】:2015-12-19 05:30:13
【问题描述】:

使用 TypeScript 1.6 可以编写函数来检查对象与接口。 (以下是MSDN的公告及使用方法。)

我的问题针对 return 表达式 return a.name === 'kitty';:

  1. 扮演一个角色?
  2. 必须所有的猫都叫kitty吗?

用户定义的类型保护

[http://blogs.msdn.com/b/typescript/archive/2015/09/16/announcing-typescript-1-6.aspx]

在早期版本的 TypeScript 中,您可以使用 if 语句 缩小类型。例如,您可以使用:

if (typeof x === "number") { … }

这有助于将信息流输入到常用的工作方式中 运行时的类型(受其他一些项目的启发) JS的类型检查)。虽然这种方法很强大,但我们希望 再推一点。在 1.6 中,您现在可以创建自己的类型保护 功能:

interface Animal {name: string; } 
interface Cat extends Animal {
  meow(); 
}

function isCat(a: Animal): a is Cat {
  return a.name === 'kitty'; 
}

var x: Animal;

if(isCat(x)) {
  x.meow(); // OK, x is Cat in this block
}

这不仅允许您使用 typeof 和 instanceof 检查, 这需要 JavaScript 可以理解的类型,但现在你可以工作了 带有接口并进行自定义分析。警卫功能表示 通过他们的“a is X”返回类型,它返回布尔值和信号 编译器如果现在预期的类型是什么。

【问题讨论】:

  • 另一个例子可以找到here
  • 顺便说一句,这对我来说似乎是一个更清晰的例子:TS Deep Dive,尤其是isFoo

标签: typescript typescript1.6


【解决方案1】:

您对return a.name === 'kitty';的问题:

1)它有作用吗?
是的,返回值决定了类型保护是通过还是失败。

2)必须所有的猫都叫kitty吗?
是的,在这种情况下,所有的猫都必须被称为 Kitty。

归根结底,这不是一个很好的例子。

一个更好的应该是......

class Animal {name: string; type: string; }
class Cat extends Animal {
  type: string = "Cat";
  meow() {}; 
}

function isCat(a: Animal): a is Cat {
  return a.type === 'Cat'; // your special checking you can replace it with any other checking expression
}

var x: Animal = new Cat();

if(isCat(x)) {
  x.meow(); // OK, x is Cat in this block
}

JSFiddle

【讨论】:

    【解决方案2】:

    考虑你的例子

    interface Animal {name: string; } - an interface
    interface Cat extends Animal { - an implementation
      meow(); 
    }
    
    function isCat(a: Animal): a is Cat {
      return a.name === 'kitty'; // your special checking you can replace it with any other checking expression
    }
    
    var x: Animal;
    
    if(isCat(x)) {
      x.meow(); // OK, x is Cat in this block
    }
    

    这个例子表明,现在,我们可以使用像a is Cat 这样的表达式,并且在已经使用检查的后续块中,a 的类型将是Catreturn a.name === 'kitty'; 表达式可以替换为

    function isCat(a: Animal): a is Cat {
      return a["meow"] != undefined; // it also would be indicate that the animal is Cat
    }
    

    它会起作用的。

    你也可以用这个替换它

    function isCat(a: Animal): a is Cat {
          return true;
    }
    

    我为你准备了example,你可以玩一下。

    结论:

    1. 表达式a is Cat 提供与a instanceof SomeClass 相同的效果,但第一个是自定义检查而不是最后一个,最后一个不适用于接口。
    2. 您的检查函数可以包含任何代码 - 这是您的选择
    3. 这个未来给了我们检查if instance is inctanceof interface的可能性

    更新

    1. 扮演它的角色?
      • 是的,它会播放。 a.name === 'kitty' - 这个表达式显示了检查给定动物 IS - Cat 的逻辑,所以,在这里你可以提供任何boolean 表达式来检查给定动物是Cat,即使你可以只返回truefalse
    2. 必须所有的猫都叫kitty吗?
      • 没有。它是由你决定。在函数 isCat 中,您可以提供任何逻辑来确保 given animal 的类型为 Cat

    【讨论】:

      猜你喜欢
      • 2021-01-22
      • 2020-11-11
      • 2018-04-13
      • 1970-01-01
      • 2018-01-03
      • 2019-01-03
      • 2018-03-26
      • 2021-10-31
      • 2021-12-20
      相关资源
      最近更新 更多