Typescript compose function

How I managed to get typescript to type check functional programming compose function?

const getName = (p) => p.name;const getLength = (str) => str.length;const isEven = (num) => num % 2 === 0;
const person = {
name: 'John',
};
const name = getName(person); // John
const length = getLength(name); // 4
const isEvenLength = isEven(length); // true
const myComposedFn = isEven(getLength(getName(person))); // true
const compose = (...fns) => (x) => fns.reduceRight((acc, cur) => cur(acc), x);
const myComposedFn = compose(isEven, getLength, getName);
const result = myComposedFn(person); // true
interface IPerson {
name: string;
}
const person: IPerson = {
name: "Mina",
};
const getName = (p: IPerson) => p.name;const getLength = (str: string) => str.length;const isEven = (num: number) => num % 2 === 0;
type ArityOneFn = (arg: any) => any;
const compose = (...fns: ArityOneFn[]) => (p: any) => 
fns.reduceRight((acc: any, cur: any) => cur(acc), p);
const myComposedFn = compose(isEven, getLength, getName);
// In vscode if you hover on that function you would see:
// const myComposedFn: (p: any) => any
  • The return type of this function isEven in order to use it as a type for myComposedFn return type. We can use built-in ReturnType .
  • The last item in a typescript tuple.
type ArityOneFn = (arg: any) => any;type PickLastInTuple<T extends any[]> = T extends [...rest: infer U, argn: infer L ] ? L : never;type FirstFnParameterType<T extends any[]> = Parameters<PickLastInTuple<T>>[any];type LastFnReturnType<T extends any[]> = ReturnType<T[0]>;
const compose = <T extends ArityOneFn[]>(...fns: T) => (p: FirstFnParameterType<T>): LastFnReturnType<T> =>  fns.reduceRight((acc: any, cur: any) => cur(acc), p);
interface IPerson {
name: string;
}
const person: IPerson = {
name: "John",
};
const getName = (p: IPerson) => p.name;
const getLength = (str: string) => str.length;
const isEven = (num: number) => num % 2 === 0;
type ArityOneFn = (arg: any) => any;
type PickLastInTuple<T extends any[]> = T extends [...rest: infer U, argn: infer L ] ? L : never;
type FirstFnParameterType<T extends any[]> = Parameters<PickLastInTuple<T>>[any];
type LastFnReturnType<T extends any[]> = ReturnType<T[0]>;
const compose = <T extends ArityOneFn[]>(...fns: T) => (p: FirstFnParameterType<T>): LastFnReturnType<T> => fns.reduceRight((acc: any, cur: any) => cur(acc), p);const myComposedFn = compose(isEven, getLength, getName);
// In vscode if you hover on that function you would see:
// const myComposedFn: (p: IPerson) => boolean

I just like javascript and typescript.