A curried function that filters by symbol is unable to get a compatible function implementation in Typescript

111 Views Asked by At

I've got a curried batching function that returns an Iterable. If you call it with a sync Iterable you get a sync Iterable, if you give an AsyncIterable you get an AsyncIterable. But can't for the life of me get the sync overload to be accepted by the function implementation.

This particular def is what's giving an error

export function batch(size: number): <T>(curriedIterable: Iterable<T>) => IterableIterator<T[]>

Here's all the code

async function* _batch<T>(size: number, iterable: AsyncIterable<T>) {
  let dataBatch: T[] = []
  for await (const data of iterable) {
    dataBatch.push(data)
    if (dataBatch.length === size) {
      yield dataBatch
      dataBatch = []
    }
  }
  if (dataBatch.length > 0) {
    yield dataBatch
  }
}

function* _syncBatch<T>(size: number, iterable: Iterable<T>) {
  let dataBatch: T[] = []
  for (const data of iterable) {
    dataBatch.push(data)
    if (dataBatch.length === size) {
      yield dataBatch
      dataBatch = []
    }
  }
  if (dataBatch.length > 0) {
    yield dataBatch
  }
}

export function batch(size: number): <T>(curriedIterable: AsyncIterable<T>) => AsyncIterableIterator<T[]>
export function batch<T>(size: number, iterable: AsyncIterable<T>): AsyncIterableIterator<T[]>
export function batch(size: number): <T>(curriedIterable: Iterable<T>) => IterableIterator<T[]>
export function batch<T>(size: number, iterable: Iterable<T>): IterableIterator<T[]>
export function batch<T>(size: number, iterable?: Iterable<T> | AsyncIterable<T>) {
  if (iterable === undefined) {
    return curriedIterable => batch(size, curriedIterable)
  }
  if (iterable[Symbol.asyncIterator]) {
    return _batch(size, iterable as AsyncIterable<T>)
  }
  return _syncBatch(size, iterable as Iterable<T>)
}
1

There are 1 best solutions below

0
On

I have duplicate definitions for function batch(size: number): when I need overloaded defs for it's return function. The following solves that.

export function batch(size: number): {
  <T>(curriedIterable: AsyncIterable<T>): AsyncIterableIterator<T[]>
  <T>(curriedIterable: Iterable<T>): IterableIterator<T[]>
}
export function batch<T>(size: number, iterable: AsyncIterable<T>): AsyncIterableIterator<T[]>
export function batch<T>(size: number, iterable: Iterable<T>): IterableIterator<T[]>

This types out alright.