Обычно я стараюсь, чтобы типы функций потока были отделены от их реализации. Это немного читаемо, когда я пишу:
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