TypeScript中的try/catch

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

作为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中错误类型,那你就肤浅了!你考虑了第三方依赖也会有其他类型的异常了吗。

总结

  1. catch的错误类型默认必须是any | unknow
  2. 如果想直接使用error.message 可以使用any或者as来避免编译出错
  3. throw可以抛出任意类型的错误
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。