【问题标题】:TypeScript type guards and "only refers to a type, but is being used as a value here."TypeScript 类型保护和“仅指一种类型,但在这里用作值”。
【发布时间】:2019-07-05 03:54:13
【问题描述】:

我使用的是Typescript 3.2.2,无法实现最基本的类型保护实现:

interface Bird {
    fly(): boolean;
}

interface Fish {
    swim(): boolean;
}

function swimIfYouCan(x: Fish | Bird) {
    if ((<Fish>x).swim) {
        return true
    }
}

这会在 WebStorm 中生成 Error:(50, 11) TS2693: 'Fish' only refers to a type, but is being used as a value here.,从 yarn 生成 SyntaxError: /Users/sea-kent/git/docket-management/webapp/src/App.tsx: Unexpected token (51:8)。启用此语法是否需要配置?

【问题讨论】:

标签: typescript


【解决方案1】:

通过检查属性是否存在来进行模式匹配的推荐方法是in 运算符:

interface Bird {
    fly(): boolean;
}

interface Fish {
    swim(): boolean;
}

function move(x: Fish | Bird) {
  if ("swim" in x) {
    return x.swim();
  } else {
    return x.fly();
  }
}

通过使用in 运算符,您可以避免断言。

【讨论】:

  • 谢谢。这适用于这个微不足道的情况,但如果我想更进一步,实际上有一个 Fish 传递给别的东西,我认为 x as Fish 更符合目标:function isFish(x: Fish | Bird): x is Fish { return (x as Fish).swim !== undefined; }
【解决方案2】:

对于您的问题,我想到了三种不同的方法。

  1. 如果你想强制转换并直接使用它,你必须使用as 运算符(正如@jonrsharpe 在 cmets 中提到的那样),例如(x as Fish).swim

  2. 使用in 运算符来检查它是否可用,例如if ('swim' in x)

  3. 最后但并非最不重要(我认为这种情况是最好的情况),只需执行一个检查实例即可检查您拥有的实例:if (x instance of Fish)

编辑:没有很好地阅读问题,您无法在运行时检查接口。但是在接口之上创建一个类并没有什么坏处

【讨论】:

  • 最后一个不起作用,因为接口在运行时不存在。
  • x instanceof Fish 给出同样的问题'Fish' only refers to a type, but is being used as a value here.
  • 如果我只想调用该方法 in 工作正常,但如果我想让Fish 传递给正在检查的其他东西,它就不会这样做。我认为x as Fish 是赢家。谢谢。
  • 是的,他没有正确阅读问题,以至于他使用的是接口而不是类
猜你喜欢
  • 2018-01-14
  • 2019-10-08
  • 2019-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-30
  • 2019-09-16
  • 2017-08-16
相关资源
最近更新 更多