You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已做类型检查仍报错: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 06:52:47