簡體   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