或者如何为返回的函数定义多个签名
我正在尝试创建一个咖喱函数,但是在定义重载方面遇到了麻烦。具体来说,如果您使用一个参数调用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)
}
谢谢!
答案 0 :(得分:2)
Overloads在不同的参数类型导致不同的返回类型时很有用。具有相同参数类型的两个不同的重载签名没有用。正如手册所说,那是因为:
[编译器]查看重载列表,然后进行第一次重载尝试以提供的参数调用该函数。如果找到匹配项,它将选择此重载作为正确的重载。
您的前两个重载具有相同的参数类型,因此将永远不会使用第二个重载。这意味着如果您使用一个参数调用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)
}
根据是否定义了parallelMap()
,调用两个不同的curriedIterable
重载。
好的,希望能有所帮助。祝你好运!