function pipe<D1, D2, D3, D4, D5, DRes, R1>(
df: DeltaFn<D1, D2, D3, D4, D5, DRes>,
r1: RiverFn<DRes, R1>
): ...?;
function pipe<D1, D2, D3, D4, D5, DRes, R1>(
df: DeltaFn<D1, D2, D3, D4, D5, DRes>,
r1: RiverFn<DRes, R1>
): ReplaceReturnType<DeltaFn<D1, D2, D3, D4, D5, DRes>, R1>;
type ReplaceReturnType<T, R> = (...a: ArgumentTypes<T>) => R;
type ArgumentTypes<T> = T extends (...args: infer U) => infer R ? U : never;
Inferring respects even type tags such as ?
optional etc.
type Unpacked<T> =
T extends (infer U)[] ? U :
T extends (...args: any[]) => infer U ? U :
T extends Promise<infer U> ? U :
T;
type T0 = Unpacked<string>; // string
type T1 = Unpacked<string[]>; // string
type T2 = Unpacked<() => string>; // string
type T3 = Unpacked<Promise<string>>; // string
type T4 = Unpacked<Promise<string>[]>; // Promise<string>
type T5 = Unpacked<Unpacked<Promise<string>[]>>; // string