https://github.com/Microsoft/TypeScript/wiki/Roadmap
type Last<T extends any[]> = T extends [...infer _, infer L] ? L : never;
type Init<T extends any[]> = T extends [...infer I, any] ? I : never;
type Pipe<T extends ((x: any) => any)[]> = Init<[(x: any) => any, ...{
[K in keyof T]: T[K] extends (x: any) => infer R ? (x: R) => any : never
}]>
declare function pipe<T extends ((x: any) => any)[] & Pipe<T>>(...f: T):
(x: (T[0] extends (x: infer A) => any ? A : never)) =>
Last<T> extends (x: any) => infer R ? R : never;
declare function toInt(s: string): number;
declare function double(n: number): number;
pipe(toInt, double); // okay
P.S.
TypeScript он статически типизирован, но к форуму декларативных языков как-то не подходит