Typescript双重同步/异步返回类型

时间:2020-08-05 09:48:02

标签: typescript asynchronous promise overloading typing

以下打字稿代码具有正确的“外部”签名,但两个return语句返回错误(playground)。

export function using<F, R = void | Promise<void>>(
  value: F,
  init: (value: F) => R
): R extends Promise<void> ? Promise<F> : F {
  const r = init(value)
  if (r === undefined) return value
  return r.then(() => value)
}

known-as-bmf建议的一个简单解决方法是使用函数重载,例如:

export function using<F>(value: F, init: (value: F) => Promise<void>): Promise<F>
export function using<F>(value: F, init: (value: F) => void): F
export function using<F>(value: F, init: (value: F) => void | Promise<void>): F | Promise<F> {
  const r = init(value)
  if (r === undefined) return value
  return r.then(() => value)
}

但是然后您在函数实现中有点松散了强类型检查,例如,以下无效,但不返回任何编译错误:

export function using<F>(value: F, init: (value: F) => Promise<void>): Promise<F>
export function using<F>(value: F, init: (value: F) => void): F
export function using<F>(value: F, init: (value: F) => void | Promise<void>): F | Promise<F> {
  const r = init(value)
  if (r === undefined) return Promise.resolve(value)
  return r.then(() => value)
}

有没有一种方法可以使第一段代码全部正常工作,同时保持强类型验证?

1 个答案:

答案 0 :(得分:1)

您可以使用function overload公开同一功能的多个签名。

示例代码here

根据您如何呼叫using,它会返回FPromise<F>

用法为here

的示例