Вы можете объявить вызываемый интерфейс, который принимает себя в качестве аргумента и возвращает результат:
interface Rec<T> {
(p: Rec<T>): T
}
const fact: (n: number) => number = ((f: Rec<(n: number)=> number>) => f(f))((g) => (n : number) => n > 0 ? n * g(g)(n - 1) : 1);
Примечание Компилятор выведет тип g
как Rec<(n: number)=> number>
Или менее общий и позволяющий компилятору выводить все, что он может версии:
interface Rec {
(p: Rec): (n: number)=> number
}
const fact = ((f: Rec) => f(f))((g) => (n) => n > 0 ? n * g(g)(n - 1) : 1);