繁体   English   中英

如何在打字稿中键入3个参数的咖喱函数?

[英]How do you type a 3 argument curried function in typescript?

或如何为返回的函数定义多个签名

我正在尝试制作一个咖喱函数,但定义超载遇到了麻烦。 具体来说,如果您使用一个参数调用parallelMap ,则可以使用1或2个参数调用下一个参数。 但是,def被标记为无效。

[ts]重载签名与函数实现不兼容。 [2394]

export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>

全面执行;

export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number): (func: (data: T) => R | Promise<R>) => (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>): (iterable: AnyIterable<T>) => AsyncIterableIterator<R>
export function parallelMap<T, R> (concurrency: number, func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>): AsyncIterableIterator<R>
export function parallelMap<T, R> (
  concurrency: number,
  func?: (data: T) => R | Promise<R>,
  iterable?: AnyIterable<T>,
) {
  if (func === undefined) {
    return <A, B>(curriedFunc: (data: A) => B | Promise<B>, curriedIterable?: AnyIterable<A>) => parallelMap(concurrency, curriedFunc, curriedIterable)
  }
  if (iterable === undefined) {
    return (curriedIterable: AnyIterable<T>) => parallelMap<T, R>(concurrency, func, curriedIterable)
  }
  return _parallelMap<T, R>(concurrency, func, iterable)
}

谢谢!

当不同的参数类型导致不同的返回类型时, 重载很有用。 具有相同参数类型的两个不同的重载签名没有用。 正如手册所述,这是因为:

[编译器]查看重载列表,然后进行第一次重载尝试以提供的参数调用该函数。 如果找到匹配项,它将选择此重载作为正确的重载。

您的前两个重载具有相同的参数类型,因此将永远不会使用第二个重载。 这意味着,如果您使用一个参数调用parallelMap() ,它将返回一个两个参数的函数,仅此而已。 它不返回单参数函数。

让我们对此进行补救。 这里的解决方案是,当您使用一个参数调用parallelMap()时,您想要返回一个重载函数,而不是仅一个参数或两个参数的函数。

另外,您希望泛型类型参数位于返回的函数上,因为当您调用parallelMap(concurrency)您不知道TR最终将是什么。

因此,将以下两个签名替换为:

export function parallelMap(concurrency: number): { 
  <T,R>(func: (data: T) => R | Promise<R>, iterable: AnyIterable<T>): AsyncIterableIterator<R>, 
  <T,R>(func: (data: T) => R | Promise<R>): (iterable: AnyIterable<T>) => AsyncIterableIterator<R> 
}

现在说“如果您使用一个参数调用parallelMap() ,它将返回另一个函数,该函数可以使用XXX和YYY类型的两个参数来调用并返回ZZZ,也可以使用一个XXX类型的参数来调用它并返回一个从YYY到ZZZ的功能。”

现在应该可以正常工作了。 请注意,由于您正在使用重载,因此以下代码并不完全正确:

  if (func === undefined) {
    return <A, B>(
      curriedFunc: (data: A) => B | Promise<B>, 
      curriedIterable?: AnyIterable<A>
    ) => parallelMap(concurrency, curriedFunc, curriedIterable) // error!
  }

毕竟,所有重载调用签名都不接受可能undefined第三个参数。 您可以使用两个或三个已定义的参数来调用它。 因此,您应该将其更改为:

  if (func === undefined) {
    return <A, B>(
      curriedFunc: (data: A) => B | Promise<B>,
      curriedIterable?: AnyIterable<A>
    ) => curriedIterable ?
        parallelMap(concurrency, curriedFunc, curriedIterable) :
        parallelMap(concurrency, curriedFunc)
  }

根据是否定义了curriedIterable ,它调用parallelMap()两个不同的重载。

好的,希望对您有所帮助。 祝好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM