javascriptgenericsflowtypearrow-functionsparameterized-types

flow generic type for function expression (arrow functions)


I usually try to keep flow function types separate from their implementation. It's a slightly more readable when I write:

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

rather than:

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

When using generic types we can write:

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

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

But how can I separate this type from a function expression?

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

What should be used for *? any would work but that's not what I want.

In haskell this is a non-issue:

identity :: a -> a
identity a = a

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

See flow.org/try


Solution

  • So I have noticed that if I use bounded generics, it'll work:

    type H<T> = <T: *>(input: T) => T;
    const h:H<*> = i => i;
    
    const a: string = h('apple');      // √
    const b: number = h(7);            // √
    const c: {} = h({ nane: 'jon' });  // √
    

    Don't ask me WHY.