funktionell programmering - TypeScript 3.7 rekursiv typ ger "typinstansiering är överdrivet djup och eventuellt oändlig"


Jag försöker koda en variadisk pipe-funktion som sätter samman ett godtyckligt antal en-argument funktioner. Denna typkontroll bör kontrollera att returtypen för en funktion är argumenttypen för nästa och så vidare.

Jag skulle förvänta mig att detta fungerar i TypeScript 3.7 som introducerar rekursiva typer, men på något sätt fungerar det inte och ger felet:

TS2589: type instantiation is excessively deep and possibly infinite

Här är min kod:

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;

FNS-typen representerar arrayen av rena funktioner och Tail-typen bör säkerställa att endast svansen av denna array returneras, men ändå markerar kompilatorn detta som en oändlig loop.

Exempel på användning:

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]>;

Felet finns på den här delen:

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

Varför är detta oändligt? Vad missar jag?

Svar #1

Variadiska typer finns på framtida färdplanen och är inte en del av 3.7.

Detta är en mycket efterlängtad funktion som verkligen kommer att möjliggöra funktionell programmering i

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