【问题标题】:Higher order function, Flow type annotations高阶函数,流类型注解
【发布时间】:2018-08-21 03:06:53
【问题描述】:

我正在尝试编写一些非常简单的功能示例来评估 Flow 类型系统。我是否遗漏了一些明显的东西,或者这个示例应该有效:

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

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

consumer(logger);

当我在Try Flow 上尝试它时,我得到“原型中找不到可调用签名”。我在本地运行时收到相同的消息(流程 0.21.0):

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

我可以通过显式声明类型别名来解决问题,但这似乎是不必要的重复(尤其是对于更复杂的模块):

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

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

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

consumer(logger);

目前我找到的唯一相关文档是:http://flowtype.org/docs/functions.html#function-based-type-annotations

假设consumerlogger 是独立的模块(甚至可能在不同的npm 包中)并且更复杂,并且logger 是导入的(es6 或commonJS)。

  • 将类型写两次(loggerloggerType)似乎不合理。
  • consumer 函数中重复logger 的类型签名似乎也不合理——我希望logFunc 参数的类型与名为logger 的函数完全匹配。特别是,对于更复杂的功能,重复这些类型会很乏味。

关于如何在不显式重复类型注释的情况下完成此操作的任何想法?

【问题讨论】:

    标签: javascript flowtype


    【解决方案1】:

    你可以使用typeof:

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

    似乎是一个 Flow 错误,在类型位置使用表达式不会给您带来有意义的错误,但我不太熟悉它,所以它可能意味着其他东西。

    不过,这里的错误体验非常令人困惑——使用类型别名可能会更好。当然,在这个 sn-p 中,我更喜欢第 15 行而不是第 1 行和第 9 行的错误

    【讨论】:

    • 谢谢!实际上,我完全忽略了 typeof 关键字。找了这么久一定是瞎了。你学的越多!是的,不幸的是,错误消息并不总是最好的。
    • 在类型位置使用时,函数名指的是函数的原型。这是为了支持 ES6 之前的样式类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 2020-05-17
    • 2013-01-16
    相关资源
    最近更新 更多