TypeScript中的trycatch

7,613 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

大家好,我是半夏👴,一个刚刚开始写文的沙雕程序员.如果喜欢我的文章,可以关注➕ 点赞 👍 加我微信:frontendpicker,一起学习交流前端,成为更优秀的工程师~关注公众号:搞前端的半夏,了解更多前端知识! 点我探索新世界!

作为JavaScript的超级,TypeScript 包含了Javascript的内容,并且还可以做到更多,例如 与Java等语言相似的类语法 public/private/protected。当然TS也实现了我们今天要说的异常捕获机制:throw用于捕获,try/catch用于处理异常。这里的异常可以是默认的异常,也可以用户自定义的异常,当然还有可能是第三方依赖提供的异常类型,例如AxiosError

JS中的六种错误类型

  1. SyntaxError:语法错误

  2. ReferenceError:引用错误,引用了不存在的东西

  3. RangeError: 超出有效范围

  4. TypeError:类型错误

  5. EvalError:eval()方法使用错误

  6. URIError:URI地址错误

TS中的try/catch

try {
	//…
} catch (err)  {
	//…
}

上面的例子,无论是JS还是TS中都是有效的代码。

无法指定错误类型

对于上面的代码,我们想要在catch明确具体的错误类型.

try {
// do something 
} catch (err:TypeError) {
}

但是编译的时候直接报错

Catch clause variable type annotation must be 'any' or 'unknown' if specified.(1196)

image-20220310200433748

这里报错信息中,明确指出:error的类型必须是any或者unknow

默认的any | unknown引发的问题

我在catch中使用err,(在JS中,Error对象有两个默认的属性,分别是name和message)。

下面的这段代码,在JS中是完全没有问题的。

try {
// do something 
} catch (err) {
    console.log(err.message);
}

但是放在TS中,编译的时候回直接报错:

image-20220310194648475

为什么会直接报这个错呢:其实很简单,在TS中,catch的error默认必须是any或者unknow类型。如果你直接使用err.message,在TS中,unknow必须要指定具体的类型才可以使用。如果你不理解这句话的话,看下面这个例子:

let u: unknown;
function user() {
 return '搞前端的半夏'
}
u=user()
console.log(u.length)

通过下图我们可以看到,即使赋值为string字符串,TS仍然默认u为unknow类型。

image-20220310195944744

as

我们回到刚才那个try/catch的例子,如果我们想要使用err.message的话,则必须指定err的类型。所以我们直接使用as来指定err的类就可以了。

try {
// do something 
} catch (err) {
    console.log((err as Error).message);
}

any

当然最简单的是直接使用any:

try {
// do something 
} catch (err:any) {
    console.log(err.message);
}

默认any | unknow的原因

为啥TS默认catch的错误类型,必须是any和unknow,其实原因很简单:我们的catch是捕获的是的throw出来的异常,throw可以抛出任何类型的异常,也可以是具体的值:

throw "搞前端的半夏"; 
throw 404; /
throw new Error("搞前端的半夏"); // 👍

既然可以抛出任何类型的异常,我们最简单的是创建一个适当的联合类型,但是能可以找到这样一个适当的联合类型吗?答案是不可能。如果你只考虑基本的数据类型以及6中错误类型,那你就肤浅了!你考虑了第三方依赖也会有其他类型的异常了吗。

catch

总结

  1. catch的错误类型默认必须是any | unknow
  2. 如果想直接使用error.message 可以使用any或者as来避免编译出错
  3. throw可以抛出任意类型的错误