已做类型检查仍报错:Property 'message' does not exist on type 'object'
TypeScript:catch块中已做类型检查仍提示“Property 'message' does not exist on type 'object'”
问题代码
try { // api call } catch (error) { if (typeof error === 'object' && error !== null && 'message' in error) { if (typeof error.message === 'string') { if (error.message.match(userRejectedError)) { // do stuff } else { // do other stuff } } } }
错误提示:Property 'message' does not exist on type 'object'
补充TSConfig配置
{ "compilerOptions": { "baseUrl": ".", "target": "es6", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "strictNullChecks": false, "noImplicitAny": false, "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve" }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules"] }
原因
在strict模式下,TypeScript会将catch块中的error类型推断为unknown。当你通过typeof error === 'object' && error !== null将其窄化为object类型后,object是一个非常宽泛的类型——它仅表示值为非原始类型,但不包含任何属性的具体信息。即便你用'message' in error做了检查,TypeScript也不会自动将object类型进一步窄化为带有message属性的类型,因为它无法确保该属性的存在是确定且持久的。
解决方案
方案一:使用类型断言明确类型
通过断言将error转为带有message属性的类型,配合已有的检查确保安全性:
try { // api call } catch (error) { if (typeof error === 'object' && error !== null && 'message' in error) { const errorWithMsg = error as { message: unknown }; if (typeof errorWithMsg.message === 'string') { if (errorWithMsg.message.match(userRejectedError)) { // do stuff } else { // do other stuff } } } }
方案二:自定义类型守卫函数
封装类型检查逻辑为类型守卫,让TypeScript能准确推断类型:
function isErrorWithStringMessage(error: unknown): error is { message: string } { return ( typeof error === 'object' && error !== null && 'message' in error && typeof (error as { message: unknown }).message === 'string' ); } try { // api call } catch (error) { if (isErrorWithStringMessage(error)) { if (error.message.match(userRejectedError)) { // do stuff } else { // do other stuff } } }
方案三:断言为Error类型(需确保抛出的是Error实例)
如果你的业务场景中,抛出的错误一定是Error类的实例,可以直接断言,但这种方式安全性较低:
try { // api call } catch (error) { const err = error as Error; if (typeof err.message === 'string' && err.message.match(userRejectedError)) { // do stuff } else { // do other stuff } }
注意:不建议通过关闭
useUnknownInCatchVariables(需在tsconfig中显式设置为false)回到any类型的错误变量,这会牺牲TypeScript的类型安全性。
内容的提问来源于stack exchange,提问作者supersize
相关产品推荐
相关产品推荐

