【问题标题】:How do I cleanly read a property in an unknown error thrown?如何在引发未知错误的情况下干净地读取属性?
【发布时间】:2020-08-21 08:05:38
【问题描述】:

在新的 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 关键字,完全类型安全)

相关链接:

【问题讨论】:

    标签: javascript typescript try-catch


    【解决方案1】:

    我已尝试检查选项,看来您的方法非常好。这是我所拥有的:

    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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-05-15
      • 1970-01-01
      • 2012-09-23
      • 2020-10-11
      • 2014-01-04
      • 2012-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多