5

I'm at a loss as to how I can make this work. I'm defining a function in typescript that essentially wraps Ramda's pipe function. I want to accept values that may or may not be functions, wrap the non-function values in constant functions, and then pass it all to pipe.

Here's the original function I tried writing:

const convertToPipeable = (values: any[]) => {
  const valueFunctions = map(valueAsFunction, values);

  return pipe(...valueFunctions);
}

At the point where I spread valueFunctions over pipe, typescript complains saying "Expected 1-6 arguments, but got 0 or more". I realise it's because pipe is typed with overloads for each argument length case (from 1 until 6), but I'm having a hard time believing that it's not possible to spread this array over it. I've tried several things, from defining the values argument as a big tuple, to using Ramda's apply method in place of the spread operator, and none of these have worked properly.

If there is no good way to type this, what might be the alternative?

Cheers!

  • 1
    Brilliant question, I've been wondering this myself. – Rich Aug 21 '18 at 01:05
  • 1
    Not having spent much time with TS typings, I don't have any suggestions. But I do have a question. I don't really understand your requirements. What good are those constant functions. The minute you add any one of them, the whole pipeline would become constant (unless some later function wasn't pure.). What am I missing? – Scott Sauyet Aug 21 '18 at 01:49
  • I'm simply looking to allow a few cases like for example changing the value being passed through the pipe to later functions (typically the constant function would be the first one, rather than somewhere in the middle of the pipe), and indeed I am looking to support situations where an impure function may be included. – Nicholas Kircher Aug 21 '18 at 03:06

1 Answers1

3

If the type declaration for pipe only accepts up to 6 arguments, but you have an array that (as far as the compiler knows) can be arbitrarily long, then the best you can do with pipe is:

return (<any>pipe)(...valueFunctions);

I'm not familiar with Ramda to know if there are other Ramda functions you may be able to use instead.

Matt McCutchen
  • 28,856
  • 2
  • 68
  • 75
  • This was going to be my fallback plan. I was hoping I could avoid using type assertions, it would be nice to find a way to do this and still hold on to the type information. – Nicholas Kircher Aug 21 '18 at 03:11
  • I've accepted your answer since it seems there really isn't any other answer for now (after having asked this same question in several other places without success). It may be a typescript limitation. Thanks for the workaround, though. – Nicholas Kircher Aug 23 '18 at 03:59