从数组返回类型的联合

returning the union of the types from arrays

我希望这个合并方法有一个 return 类型的联合,所有不同的数组类型都传递给它。

type AnyIterable<T> = Iterable<T> | AsyncIterable<T>

async function* merge<T>(...iterables: Array<AnyIterable<T>>) {
  for (const iterable of iterables) {
    yield* iterable
  }
}

merge([1, 2, 3], ['1', '2', '3'])
// Argument of type 'string[]' is not assignable to parameter of type 'AnyIterable<number>'.
// Property '[Symbol.asyncIterator]' is missing in type 'string[]' but required in type 'AsyncIterable<number>'.ts(2345)

但我收到了那个错误。显然这是预期的,但我不知道如何键入它以从可迭代数组中获取值。

嗯,我认为人们通常 want errors like this to happen,因为异构数组不如同构数组常见,并且总是扩大直到它起作用的类型推断不会捕获实际错误。

如果你想解决这个问题,可能会转向另一个方向:强制类型推断成功,然后 calculate 如果你需要它 T 的值:

async function merge<I extends Array<AnyIterable<any>>>(...iterables: I) {
  for (const iterable of iterables) {
  }
}

type UnArrayAnyIterable<A extends Array<AnyIterable<any>>> = 
  A extends Array<AnyIterable<infer T>> ? T : never;

现在成功了:

merge([1, 2, 3], ['1', '2', '3']); // I inferred as the tuple `[number[], string[]]`

如果你想要 T 你可以使用 UnArrayAnyIterable:

declare function foo<I extends Array<AnyIterable<any>>>(...iterables: I): UnArrayAnyIterable<I>;
const ret = foo([1, 2, 3], ['1', '2', '3']); // string | number

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