问题描述
在TS的新的4.0版本中,we can now typed error as unknown。
之前,此代码还可以,因为err
被键入为any
:
catch (err) {
console.error(err.message);
}
在TS 4.0中,我们可以将err
键入为unkNown
,但是代码不会编译
catch (err: unkNown) {
console.error(err.message); // Error: Object is of type 'unkNown'
}
因此,我们可以使用as
关键字手动键入它:
catch (err: unkNown) {
const typedError = err as { message: string };
console.error(typedError.message);
}
但这感觉很脏,as
关键字不是安全的关键字,并且开发人员仍然会错过很多情况。例如,如果err
为空怎么办?
我尝试了类似的方法,但是没有用:
catch (err: unkNown) {
if(err && typeof err === 'object' && 'message' in err) {
console.error(err.message); // Error: Property 'message' does not exist on type 'object'
}
}
从unkNown
对象读取属性的最干净安全的方法是什么? (没有as
关键字,完全类型安全)
相关链接:
解决方法
我已经尝试检查选项,看来您的方法还不错。这是我所拥有的:
const hasMessage = (err: any): err is {message: string} =>
err && typeof err === 'object' && "message" in err;
try {
// Some code here
} catch (err: unknown) {
// Just to catch all 'standard' errors
if (err instanceof Error) {
console.error(err.message);
}
// Use a typeguard for 'err' (just tell the compiler,that it has 'message')
if (hasMessage(err)) {
console.error(err.message);
}
// Your original 'if',but with a typecast inside
// (because we are sure it has 'message' in 'err')
if (err && typeof err === 'object' && "message" in err) {
const typedError = err as { message: string };
console.error(typedError.message);
}
}