6

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
)
thomas-peter
  • 7,738
  • 6
  • 43
  • 58
  • 1
    There are several TS typing files for Ramda out there, but, as I understand it, TS does not yet have the capability to handle some of the higher-order manipulations done by Ramda. `compose` is probably top of the list. But I don't know the details. – Scott Sauyet Feb 20 '19 at 17:09
  • 1
    Thanks Scott, it makes no sense to use TypeScript in my opinion but I have don't have a choice. – thomas-peter Feb 22 '19 at 09:54

1 Answers1

21

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)

Peak
  • 349
  • 2
  • 6
  • 1
    With your first (compose) example, I get an error on line 2: `Type '{ [key: string]: string | number; }' does not satisfy the constraint 'any[]'.` I'm using @types/ramda 0.28.13. What did you use? – Bennett McElwee Jun 01 '22 at 22:37