type Apply<F, A> = F extends (arg: infer P) => infer R↵
? A extends P ? R : never↵
: never;↵
type Compose<F, G> = F extends (a: infer A) => infer B↵
? G extends (b: B) => infer C ? (a: A) => C : never↵
: never;↵
type ToNumber = (s: string) => number;↵
type Double = (n: number) => number;↵
type Composed = Compose<ToNumber, Double>;↵
const toNumber = (s: string) => parseInt(s);↵
const double = (n: number) => n * 2;↵
const composed: Composed = (s) => double(toNumber(s));↵
console.log(composed("21"));