Christoffer
Christoffer

Reputation: 2125

Higher order function, Flow type annotations

I'm trying to write some very simple, functional examples to evaluate the Flow type system. Am I missing something obvious, or should this sample work:

function logger (message: string): void {
    console.log(message);
}

function consumer (logFunc: logger) {
    logFunc('foo');
}

consumer(logger);

When I try it on Try Flow I get "Callable signature not found in prototype". I'm getting the same message when run locally (flow 0.21.0):

  8:     logFunc('foo');
         ^^^^^^^^^^^^^^ function call. Callable signature not found in
  8:     logFunc('foo');
         ^^^^^^^ prototype

I can solve the problem by declaring a type alias explicitly, but that seems like unnecessary duplication (especially for more complex modules):

type loggerType = (message: string) => void;

function logger (message: string): void {
    console.log(message);
}

function consumer (logFunc: loggerType) {
    logFunc('foo');
}

consumer(logger);

The only relevant documentation I've found so far is: http://flowtype.org/docs/functions.html#function-based-type-annotations

Imagine that consumer and logger are separate modules (perhaps even in separate npm packages) and are more complicated, and logger is imported (es6, or commonJS).

Any ideas on how to accomplish this without explicitly repeating the type annotations?

Upvotes: 4

Views: 1471

Answers (1)

Ryan Cavanaugh
Ryan Cavanaugh

Reputation: 220954

You can use typeof:

function consumer (logFunc: typeof logger) {
    logFunc('foo');
}

Seems like a Flow bug that using an expression in a type position doesn't give you a meaningful error, but I'm not as familiar with it so maybe it means something else.

The error experience here is pretty confusing, though -- you may be better off with a type alias. Certainly in this snippet I would prefer an error on line 15 rather than on 1 and 9

enter image description here

Upvotes: 7

Related Questions