3

I'm trying to code a variadic pipe function which composes an arbitrary number of one-argument pure functions. This typing should check that the return type of one function is the argument type of the next and so on.

I would expect this to work in TypeScript 3.7 which introduces recursive types but somehow it doesn't work and gives the error:

TS2589: type instantiation is excessively deep and possibly infinite

Here's my code:

type Tail<T extends any[]> = ((...t: T) => void) extends ((x: any, ...u: infer U) => void) ? U : never;

type Pipe<FNS extends unknown[]> = FNS extends [(a: infer A) => infer B, (b: infer B) => infer C] ? C :
                                 FNS extends [(a: infer A) => infer B, (b: infer B) => infer C, Pipe<[...Tail<FNS>[]]>] ? C : never;

The FNS type represents the array of pure functions and the Tail type should make sure that only the tail of this array is returned, but still the compiler marks this as an infinite loop.

Usage example:

const numToString = (n: number): string => n.toString();
const toUpper = (s: string): string => s.toUpperCase();

// this works, Foo evaluates to string
type Foo = Pipe<[typeof numToString, typeof toUpper]>;

// this doesn't work, Foo is not evaluated
type Foo = Pipe<[typeof numToString, typeof toUpper, typeof toUpper]>;

The error is on this part:

Pipe<[...Tail<FNS>[]]>

Why is this infinite? What am I missing?

Danny Moerkerke
  • 452
  • 4
  • 18
  • I manages to get rid of the error by changing the definition of `Pipe` to this: `type Pipe = FNS extends [(a: infer A) => infer B, (b: infer B) => infer C] ? C : FNS extends [(a: infer A) => infer B, (b: infer B) => infer C, Pipe>] ? C : never;` but this evaluates to `never` instead of `string` so it's not correctly typed: `type Foo = Pipe<[typeof numToString, typeof toUpper, typeof toUpper]>;` – Danny Moerkerke Oct 14 '19 at 20:58
  • TypeScript 3.7 is beta. I'm not saying that's the reason but why are you using a version that isn't yet officially out? For testing purposes? – jperl Oct 17 '19 at 11:19
  • I have not tried to reproduce the error myself but if it is a bug, let the devs know about it. – jperl Oct 17 '19 at 11:21
  • @jperl yes for testing purposes – Danny Moerkerke Oct 18 '19 at 14:08
  • [Related](https://stackoverflow.com/questions/53173203/typescript-recursive-function-composition)... – Jared Smith Oct 22 '19 at 21:13

1 Answers1

1

Variadic types are on the future roadmap and not part of 3.7.

This a highly anticipated feature that will really enable functional programming in

Typescript https://github.com/Microsoft/TypeScript/issues/5453

Damian Green
  • 6,895
  • 2
  • 31
  • 43