Struggling to get TypeScript to correctly infer the underlying iterable type for the function spread
. The purpose of this function is to take an iterable of iterable types, infer the type of the underlying iterable, and return a new iterable with that inferred type.
interface Output<T, R> {
(i: Iterable<T>): Iterable<R>;
}
function pipe<T, A>(i: Iterable<T>, p0: Output<T, A>): Iterable<A>;
function pipe(i: Iterable<any>, ...p: Output<any, any>[]): Iterable<any> {
return []; // dummy iterable
}
// Attempting to implement the following function:
function spread<T extends Iterable<R>, R>(): Output<T, R> {
return (iterable: Iterable<T>) => ({
[Symbol.iterator](): Iterator<R> {
return null as any; // dummy, for now
}
});
}
pipe(['text'], spread());
// expected types: spread => Output<string, string>, pipe => Iterable<string>
// actual types: spread => Iterable<string, unknown>, pipe => Iterable<unknown>
pipe([[1, 2], [3, 4]], spread());
// expected types: spread => Output<number[], number>, pipe => Iterable<number>
// actual types: spread => Output<number[], unknown>, pipe => Iterable<unknown>
While the template signature for the function spread
seems correct in theory, I'm puzzled by why the iterable type resolves to unknown
in the examples above.
As a result, spread
infers as <T, unknown>
, causing pipe
to fail in type inference as well.
This issue arose while working on the iter-ops library. While I have successfully implemented various operators, I hit a roadblock with the spread
operator's type inference.
UPDATE
With guidance from Titian Cernicova-Dragomir, I was able to successfully finalize the spread
operator :)