Typescript 柯里化和异步函数

Typescript Currying and Async Functions

Typescript@4.0.0rc9

在打字稿中为手动柯里化函数编写定义。它们在最终 return 值是非承诺时起作用,但在它是承诺时失败。例如,这有效:

function test (
  a: number,
): (
  b: number,
) => number
function test (
  a: number,
  b: number,
 ):  number
function test (a, b?) {
  if (b === undefined)
    return function (b: number) { test(a, b) }
  return a + b
}

虽然失败了:

function asynctest (
  a: number,
): (
  b: number,
) => Promise<number>
function asynctest (
  a: number,
  b: number,
 ):  Promise<number>
async function asynctest (a, b?) {
  if (b === undefined)
    return function (b: number) { return asynctest(a, b) }
  return await a + b
}

VSCode 的内置类型检查器建议当提供 1 个参数时 return 由 asynctest 编辑的类型是预期的 (b: number) => Promise<number>

在写这个问题的过程中我解决了。

一个异步函数必须 return 一个 promise,所以在传递一个参数的情况下,而不是 returning 一个函数,它 returning 一个 Promise of a功能。所以正确的异步等待版本是:

function asynctest (
  a: number,
): Promise<(
  b: number,
) => Promise<number>>
function asynctest (
  a: number,
  b: number,
 ):  Promise<number>
async function asynctest (a, b?) {
  if (arguments.length === 1)
    return function (b: number) { return asynctest(a, b) }
  return await a + b
}

替代版本是直接使用 promises 而不是使用 async-await(我认为这样更整洁):

function promisetest (
  a: number,
): (
  b: number,
) => Promise<number>
function promisetest (
  a: number,
  b: number,
 ):  Promise<number>
function promisetest (a, b?) {
  if (arguments.length === 1)
    return function (b: number) { return promisetest(a, b) }
  return new Promise(a + b)
}