Да, мой ответ кажется хаком до тех пор, пока поток не найдет решение, но на самом деле оно работает, как ожидалось, и тип проверяет неправильное использование Но спасибо за ваш подробный ответ.

чно стараюсь отделить типы потоковых функций от их реализации. Это немного более читабельно, когда я пишу:

type Fn = string => string;
const aFn: Fn = name => `hello, ${ name }`;

скорее, чем:

const aFn = (name: string): string => `hello, ${ name }`;

При использовании универсальных типов мы можем написать:

const j= <T>(i: T): T => i;

const jString: string = j('apple'); // √
const jNumber: number = j(7);       // √

Но как я могу отделить этот тип от выражения функции?

type H<T> = (input: T) => T;
const h:H<*> = i => i;              // --> WHAT SHOULD GO FOR '*'?

const hString: string = h('apple'); // X error
const hNumber: number = h(7);       // X error

Что следует использовать для*? any будет работать, но это не то, что я хочу.

В haskell это не проблема:

identity :: a -> a
identity a = a

identity "a-string" // √
identity 666        // √

Видетьflow.org/try

Ответы на вопрос(3)

Ваш ответ на вопрос