Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use compose in Typescript?

Im having problems using compose in Typescript....

const rawHeaders = R.compose(
  R.join('\n'),
  R.map(x=>`${x[0]}: ${x[1]}`),
  R.toPairs
)

I have tried the below, but it's brutal. Anyone know a way to make this work more elegantly?

const rawHeaders:Function = R.compose(
  R.join('\n'),
  R.map((x:[String, String]) =>`${x[0]}: ${x[1]}`),
  (x:{s:String})=>R.toPairs(x))
)

I have also tried to use ts-ignore, which at present seems to be the best option.

const rawHeaders = R.compose(
  R.join('\n'),
  // @ts-ignore
  R.map(x=>`${x[0]}: ${x[1]}`),
  // @ts-ignore
  R.toPairs
)
like image 539
thomas-peter Avatar asked Feb 20 '19 12:02

thomas-peter


People also ask

How do I use TypeScript compose?

const compose = (... fns) => (x) => fns. reduceRight((acc, cur) => cur(acc), x); This is a higher order function that accepts array of functions and return a function that accept an object and if called it returns the result of running these functions (from right to left) on that object.

How do I use compose in Redux?

Compose is used when you want to pass multiple store enhancers to the store. Store enhancers are higher order functions that add some extra functionality to the store. The only store enhancer which is supplied with Redux by default is applyMiddleware however many other are available.

What is compose function in JavaScript?

Function composition is an approach where the result of one function is passed on to the next function, which is passed to another until the final function is executed for the final result. Function compositions can be composed of any number of functions.

What is pipe function in TypeScript?

A pipe is a function or operator that allows us to pass the output of a function as the input of another. JavaScript and TypeScript don't support pipes natively (as an operator), but we can implement our pipes using the following function: const pipe = <T>(... fns: Array<(arg: T) => T>) => (value: T) => fns.


1 Answers

Have you tried leveraging the typing of compose itself? You can give it the arguments and the return values of each function in the compose like so:

const rawHeaders = R.compose<
  { [key: string]: string | number }, // Argument
  Array<[string, string]>, // Return of toPairs
  string[], // Return of map
  string // Return of join
>(
  R.join('\n'),
  R.map(x => `${x[0]}: ${x[1]}`),
  R.toPairs
);

Personally I prefer to use pipe as the typings match up to the argument order within pipe, compared to compose which is backwards:

const rawHeaders = R.pipe<
  { [key: string]: string | number }, //Argument
  Array<[string, string]>, // return of toPairs
  string[], // return of map
  string // return of join
>(
  R.toPairs,
  R.map(x => `${x[0]}: ${x[1]}`),
  R.join('\n')
);

Either way, each function in the pipe/compose gets the right value and you don't need to decorate the function within the pipe exclusively(unless you start using something like R.flip). It's verbose, but it works.

(you can specify as many args as you need for the first function, the overloads will handle the rest btw)

like image 117
Peak Avatar answered Sep 25 '22 02:09

Peak