[英]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)
您不知道T
和R
最终将是什么。
因此,将以下两个签名替换为:
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.