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

TypeScript异步方法try/catch中err报unknown类型的原因及解决办法

报错原因

这个现象的本质是TypeScript的类型校验规则导致,和异步方法本身没有直接关联:

  • TypeScript 4.4及以上版本新增了useUnknownInCatchVariables编译选项,开启该选项后,所有catch块捕获的错误变量默认类型为unknown,而非早期版本的any,unknown类型的变量不允许直接访问任意属性,所以会触发你遇到的报错。
  • 你观察到的同步方法无报错、异步方法报错的差异,通常是两个原因导致:一是你的项目TS配置对异步代码的类型校验严格度更高,二是同步方法的catch块要么没有访问err的属性,要么已经提前做了类型适配,没有触发校验逻辑。
  • 异步方法中await操作可能抛出的错误类型本身无法提前预知,TS也会针对这类场景默认做更严格的类型检查,所以会优先触发unknown类型的提示。

修复方案

你可以根据项目的实际情况选择以下任意一种方案:

方案1:类型收窄处理(最安全,推荐)

先判断err的类型再访问属性,完全符合TS的类型安全要求,也能兼容运行时可能抛出非Error类型值的极端场景:

async createOrganization(dbSession: ClientSession, organization: IOrganization): Promise<IOrganization> {
  try {
    // @ts-ignore
    const newOrganization = new this.Model(organization)
    // @ts-ignore
    await newOrganization.save()
    // @ts-ignore
    return newOrganization
  } catch (err: unknown) {
    if (err instanceof Error) {
      throw new OrganizationCreationError(err.message)
    }
    // 处理非Error类型的抛出值
    throw new OrganizationCreationError(String(err))
  }
}

方案2:全局关闭catch变量的unknown校验

如果项目不需要这么严格的类型校验,可以直接修改tsconfig.json的编译配置:

{
  "compilerOptions": {
    "useUnknownInCatchVariables": false
  }
}

配置生效后所有catch块的err变量默认会是any类型,不会再触发该报错,但是会损失类型安全性,不推荐中大型项目使用。

方案3:类型断言快速修复(临时应急用)

如果确定当前场景抛出的错误一定是Error类实例,可以直接用类型断言绕过校验,写法最简单:

catch (err) {
  throw new OrganizationCreationError((err as Error).message)
}

注意该方案没有运行时校验,如果实际抛出的不是Error实例,会导致访问message属性时报错,只适合临时应急使用。


内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:36:04