I've written this simple compose function which works just fine. However in order to assure type safety I had to resort to using generics to provide the compiler with type hints even though it's easily possible to infer the signature of "upperCaseAndLog".
const compose = <T, R>(...fns: Array<(a: any) => any>) => (a: T): R =>
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<string, void>(
greet,
toUpperCase,
log
);
upperCaseAndLog("bill");
Am I missing something, is there a more elegant way of accomplishing the same goal? I assume that languages like F# or Haskell would be able to infer the types without any additional information.