簡體   English   中英

使用 generics 將數組返回類型與任意數量的輸入匹配

[英]Match array return types with arbitrary number of inputs using generics

如果用戶傳入類型[Iterable<T>]我想返回類型[T]如果用戶傳入[Iterable<T>, Iterable<U>]我想返回類型[T, U] 我想對輸入數組中的任意數量的元素繼續這個。

有沒有一種方法可以通用地定義以下 function 的類型,以便它適用於任意數量的輸入,而不是繼續定義 function 的重載,增加通用數量?

到目前為止,這是我所擁有的,但當然它只支持最多 5 個定義的輸入。 我可以讓它適用於任意數量的輸入嗎?

export function linkIterables<T>(
  iterables: [Iterable<T>],
): Iterable<[T]>;
export function linkIterables<T, U>(
  iterables: [Iterable<T>, Iterable<U>],
): Iterable<[T, U]>;
export function linkIterables<T, U, V>(
  iterables: [Iterable<T>, Iterable<U>, Iterable<V>],
): Iterable<[T, U, V]>;
export function linkIterables<T, U, V, W>(
  iterables: [Iterable<T>, Iterable<U>, Iterable<V>, Iterable<W>],
): Iterable<[T, U, V, W]>;
export function linkIterables<T, U, V, W, X>(
  iterables: [Iterable<T>, Iterable<U>, Iterable<V>, Iterable<W>, Iterable<X>],
): Iterable<[T, U, V, W, X]>;
export function* linkIterables<T>(
  iterables: Iterable<Iterable<T>>,
): Iterable<T[]> {
  const iters = [...iterables].map(u => u[Symbol.iterator]());
  while (true) {
    let done = true;
    const results = [];
    for (const iter of iters) {
      const result = iter.next();
      if (!result.done) {
        done = false;
      }
      results.push(result.value);
    }
    if (done) {
      return results;
    }
    yield results;
  }
};

是的,您可以在數組和元組類型上使用映射類型來表示將 output 元組類型T轉換為輸入元組類型的一般操作,其中 T 中的每個數字索引I將具有Iterable<T[I]> T的屬性. 像這樣:

export function linkIterables<T extends any[]>(
  iterables: [...{ [I in keyof T]: Iterable<T[I]> }]
): Iterable<T>;

請注意,將iterables的類型包裝在[... ]中使用可變元組類型語法來暗示我們希望編譯器盡可能將iterables解釋為元組類型,而不僅僅是數組。 讓我們試試看:

const result = linkIterables([
  [1, 2],
  ["a", "b"],
  [true, false],
  [new Date(), new Date()],
  [document, document],
  [null, null]
]);

// const result: Iterable<[number, string, boolean, Date, Document, null]>

看起來挺好的!

游樂場代碼鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM