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

能否为基于回调和参数生成Promise的函数实现TypeScript类型安全?

解决方案

通过TypeScript泛型+内置类型工具约束参数类型,即可实现类型检查和参数自动提示,改造后的代码如下:

// 定义符合业务场景的函数类型约束:第一个参数为接收返回值的回调,后续为自定义参数,无返回值
type CallbackFirstFunc<CallbackResult = unknown, RestParams extends any[] = any[]> = (
  callback: (result: CallbackResult) => void,
  ...restParams: RestParams
) => void;

async callbackToPromise<CallbackResult, RestParams extends any[]>(
  func: CallbackFirstFunc<CallbackResult, RestParams> | undefined,
  ...args: RestParams
): Promise<CallbackResult> {
  // 原有业务逻辑保持不变
  if (func === undefined) {
    console.warn('Function undefined in callbackToPromise.')
    return Promise.reject(
      new Error('Function undefined in callbackToPromise.')
    )
  }
  const call = new Promise<CallbackResult>((resolve, reject) => {
    func((resolveStr: CallbackResult) => {
      if (resolveStr !== undefined) {
        return resolve(resolveStr)
      } else {
        return reject(new Error('No data returned'))
      }
    }, ...args)
  })
  return call
}

实现逻辑

  • 用泛型CallbackResult指代回调函数接收的返回值类型,也就是最终Promise返回的结果类型,无需再手动标注any
  • 用泛型RestParams指代目标函数除第一个回调外的所有参数类型集合,TypeScript会根据传入的func自动推导该类型
  • 约束传入的...args必须匹配RestParams,参数类型/数量不匹配时会直接触发编译报错,同时编辑器会自动提示参数类型

注意事项

之前遇到的Type 'number | void' is not assignable to type 'number'报错和本工具函数的类型逻辑无关,是catch块无返回值导致的,推荐用try/catch结构替代Promise链式catch写法避免该问题:

let result: number;
try {
  result = await this.helpers.callbackToPromise(
    this.wrappedWindow.external.RemoveProblem,
    prid,
    stopDate,
    isApprox,
    reason
  )
} catch (error: Error) {
  console.error(`Error removing problem: ${error.message}`)
  // 按需选择抛出错误或者给result赋值默认值
  throw error
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:24:04