catch 中的错误对象的类型是未知的

时间:2021-07-04 00:37:22

标签: typescript try-catch

我有以下代码:

try {
  phpDoc(vscode.window.activeTextEditor);
} catch (err) {
  console.error(err);
  vscode.window.showErrorMessage(err.message);
}

然而,err.messageObject is of type 'unknown'.ts(2571) 上得到错误 err.,但我无法在 catch (err: Error) 中输入对象。

我该怎么办?

2 个答案:

答案 0 :(得分:2)

这是因为任何东西都可以抛出,因此unknown

const fn = () => {
  throw 'foo';
};
try {
  fn();
} catch(e) {
  console.log(e);
  console.log(e instanceof Error);
  console.log(e === 'foo');
}

在访问 err 属性之前,您需要检查 message 是否确实是错误以缩小范围。

try {
  phpDoc(vscode.window.activeTextEditor);
} catch (err) {
  console.error(err);
  if (err instanceof Error) {
    vscode.window.showErrorMessage(err.message);
  } else {
    // do something else with what was thrown, maybe?
    // vscode.window.showErrorMessage(String(err));
  }
}

答案 1 :(得分:0)

作为对CertainPerformanceone的补充回答:

直到 TypeScript 4.0,catch 子句绑定被设置为 any,从而允许轻松访问 message 属性。这是不安全的,因为不能保证抛出的内容会继承自 Error 原型 - 只是发生我们除了错误之外什么都不抛出最佳做法:

(() => {
    try {
        const myErr = { code: 42, reason: "the answer" };
        throw myErr; //don't do that in real life
    } catch(err) {
        console.log(err.message); //undefined
    }
})();

TypeScript 4.0 introduced 一个更安全的 catch 子句选项,允许您将参数注释为 unknown,迫使您要么执行显式类型断言,要么更好地类型保护(这使得该子句在编译时和运行时都安全)。

但是,为了避免破坏大部分代码库,您必须明确选择加入新行为:

(() => {
    try {
        throw new Error("ouch!");
    } catch(err: unknown) {
        console.log(err.message); //Object is of type 'unknown'
    }
})();

TypeScript 4.4 引入了一个名为 useUnknownInCatchVariables 的新编译器选项,它强制执行此行为。默认情况下它是 false,但如果您打开了 strict 选项(正如您应该的那样),它被打开,这很可能是您首先收到错误的原因。< /p>