【问题标题】:Narrowing down error type in catch缩小 catch 中的错误类型
【发布时间】:2017-07-29 02:56:19
【问题描述】:

对于这段代码

try {
  throw new CustomError();
}
catch (err) {
  console.log(err.aPropThatDoesNotExistInCustomError);
}

errany 并且不会触发类型错误。如何将其缩小到预期的错误类型?

【问题讨论】:

标签: typescript typescript2.0


【解决方案1】:

您需要自己执行检查以缩小 catch 块内的范围。编译器不知道也不相信err 肯定会是CustomError

try {
  throw new CustomError();
}
catch (err) {
  console.log('bing');
  if (err instanceof CustomError) {
    console.log(err.aPropThatIndeedExistsInCustomError); //works
    console.log(err.aPropThatDoesNotExistInCustomError); //error as expected
  } else {
    console.log(err); // this could still happen
  }
}

例如,这是我对CustomError 的邪恶实现:

class CustomError extends Error {
  constructor() {
    super()
    throw new Error('Not so fast!');  // The evil part is here
  }
  aPropThatIndeedExistsInCustomError: string;
}

在这种情况下,err不会CustomError。我知道,这可能不会发生,但关键是编译器不会为您自动缩小范围。如果您完全确定类型,则可以分配给另一个变量:

try {
  throw new CustomError();
}
catch (_err) {
  const err: CustomError = _err;
  console.log(err.aPropThatDoesNotExistInCustomError); // errors as desired
}

但请记住,如果您弄错类型,可能会在运行时遇到麻烦。

祝你好运!

P.S.:有关更多信息,请参阅 TypeScript 问题 #8677#9999

【讨论】:

  • 谢谢。 instanceof 在这里不是问题,错误类型是明确的,而且它是CustomError 类型,不一定是实例。 const err: CustomError = _err 看起来像一个非常丑陋的黑客。我查了#8677和#9999,貌似是通过PR关闭的,但是不知道PR是怎么解决问题的,
  • 我不明白你所说的instanceof 是什么意思。如果您执行throw new CustomError(),则您已创建(并抛出)CustomError 类的新实例。当且仅当err 的构造函数是CustomError 构造函数时,检查err instanceof CustomError 将返回true
  • 过去你甚至无法使用 instanceof 或其他类型保护来缩小范围(所以你几乎不得不将捕获的对象分配给一个新的缩小变量),但 #9999 修复了它的那一部分。
  • 在这个例子中它肯定是。在任何其他情况下,它可以是一个使用 CustomError 接口引发错误的函数(这就是 err: CustomError 所暗示的)。感谢您的通知,我注意到 instanceof 在某些时候开始以积极的方式影响类型,但不确定这种变化来自哪里。
  • 至于引入新变量的丑陋/骇人听闻:不幸的是,这是强制编译器假设错误属于您认为的类型的最直接方法。你不能注释被捕获对象的类型;您所能做的就是使用类型保护来缩小范围或将其分配给新变量。如果有人可以提出更简洁的答案,我会很感兴趣,但听到它会感到惊讶。从阅读 #8677 和 #9999 来看,这是最好的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 2022-12-20
  • 2022-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多