Typescript не может вывести такие связанные типы (связанные в том смысле, что аргумент функции зависит от результата предыдущей функции).
Вы даже не можете определить сигнатуру compose
достаточно широко, чтобы она работала для ряда функций. Что мы можем сделать, это определить перегрузки, которые принимают до заданного числа функций:
type Fn<A, R> = (a: A) => R // just to be a bit shorter in the compose signature, you can use teh function signature directly
function compose<T, P1, P2, R>(fn1: Fn<T, P1>, fn2: Fn<P1, P2>, f3: Fn<P2, R>) : Fn<T, R>
function compose<T, P1, R>(fn1: Fn<T, P1>, f2: Fn<P1, R>) : Fn<T, R>
function compose(...fns: Array<(a: any) => any>) {
return function (a: any) {
return fns.reduce((b, f) => f(b), a);
}
}
const greet = (s: string) => "Hello " + s;
const toUpperCase = (s: string) => s.toUpperCase();
const log = console.log;
const upperCaseAndLog = compose(
greet,
toUpperCase,
log
);
upperCaseAndLog("bill");//(a: string) => void