2
\$\begingroup\$

Here I created a typed version of lodash flow that offers more specific typing.

I'm curious if this exists in any other library, which optimized in tying any way — offering mainly it up to the world as a better version of flow.

  1. The return value is set to the return in the last passed function
  2. The input value is set to the input of the first given function
  3. In between functions are checking the return types from the proceeding function match the inputs of the next.

Here's the code:

import * as _ from 'lodash';
namespace Compose {
 export type ReadFuncs = readonly ((x: any) => any)[]
 export type Tail<T extends ReadFuncs> = ((...a: T) => void) extends ((h: any, ...r: infer R) => void) ? R : never;
 export type Func = (...any) => any
 export type Funcs = Func[]
 export type LengthOfTuple<T extends any[]> = T extends { length: infer L } ? L : never;
 export type LastInTuple<T extends ReadFuncs> = T[LengthOfTuple<Tail<T>>];
 export type LastFnReturns<Fns extends ReadFuncs> = ReturnType<LastInTuple<Fns>>
 export type FirstFnParam<Fns extends ReadFuncs> = Parameters<Fns[0]>
 export type CheckFns<T extends readonly ((x: any) => any)[]> = { [K in keyof T]:
 K extends keyof Tail<T> ? (
 [T[K], Tail<T>[K]] extends [(x: infer A) => infer R, (x: infer S) => any] ? (
 [R] extends [S] ? T[K] : (x: A) => S
 ) : never
 ) : T[K]
 }
}
function compose<T extends Compose.ReadFuncs, R extends Compose.LastFnReturns<T>>(...t: Compose.CheckFns<T>) {
 return (...input: Compose.FirstFnParam<T>) => {
 return _.flow(t)(...input) as R
 }
}
const x = compose(
 (foo: string) => `wrapFoo1(${foo})`,
 (foo: string) => `wrapFoo2(${foo})`,
 (foo: string) => `wrapFoo3(${foo})`,
 (foo: string) => `wrapFoo4(${foo})`,
 (value: string): number => value.length,
)
const velvet = x('meow')
console.log(velvet)
RoToRa
11.6k1 gold badge24 silver badges51 bronze badges
asked Nov 18, 2019 at 18:27
\$\endgroup\$

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.