多态匿名函数类型别名
Polymorphic Anonymous Functions Type Aliases
似乎命名function()
语法的类型声明与匿名函数语法之间存在微妙的差异:
type F<X, Y> = (x: X) => Y
// works:
function apply<X, Y>(f: F<X, Y>, x: X) : Y {
return f(x)
}
// works:
const apply0 : <X, Y>(f: F, x: X) => Y = (f, x) => f(x)
// doesn't work
const apply1 : <X, Y>(f: F<X, Y>, x: X) => Y = (f, x) => f(x)
流控制台代码段
我需要从匿名apply
函数的参数中对类型F<X, Y>
的任何引用中删除泛型类型注释,以便类型检查器工作。
这是违反直觉的
[编辑:]但似乎流量能够类型检查apply1
调用,即使它无法类型检查apply1
本身:
apply1(x => x * 2, 'a') // error: ^ string. This type is incompatible with
apply1(x => x * 2, 1) // works
一般:
// works:
type Apply<X, Y> = <X, Y>(f: F, x: X) => Y
const apply : Apply = (f, x) => f(x)
// doesn't work:
type Apply1<X, Y> = <X, Y>(f: F<X, Y>, x: X) => Y
const apply1 : Apply1 = (f, x) => f(x)
流控制台代码段
我必须从类型别名Apply
的参数中删除泛型类型注释X, Y
,以便Flow进行类型检查。
这是预期的行为还是我错过了什么?
TL;DR: Try
const apply1 = <X, Y>(f: F<X, Y>, x: X): Y => f(x)
首先,正如@squint在评论中提到的,没有类型参数的F
隐含地意味着F<any, any>
,这就是为什么apply0
在你的例子中工作。
那么为什么你的apply1
有一个错误?这是因为Flow不推断泛型。所以当你写
const apply1 : <X, Y>(f: F<X, Y>, x: X) => Y = (f, x) => f(x)
赋值的右边是
(f, x) => f(x)
和Flow不能推断出这个箭头函数是多态的。所以你可以像这样给RHS添加类型参数:
const apply1 : <X, Y>(f: F<X, Y>, x: X) => Y = <X, Y>(f: F<X, Y>, x: X): Y => f(x)
,这应该修复错误。但是此时,左边的类型注释不再需要了。可以简化为
const apply1 = <X, Y>(f: F<X, Y>, x: X): Y => f(x)
进一步阅读
Avik Chaudhuri在一个类似的堆栈溢出问题上写了一个简短的解释,然后链接到GitHub上的一个类似的答案
相关文章:
- 为什么会出现错误;未捕获的类型错误:undefined不是函数;
- 如何在DOM元素上按类型构建此函数
- 同样,同样的错误'ahorcado.js:26未捕获类型错误:无法读取属性'beginPath'
- YUI3 IO实用程序是否可以根据给定的内容类型标头值自动序列化数据
- Webpack/Rect:遵循egghead.io教程,但出现错误:您可能需要一个合适的加载程序来处理此文件类型
- 如何从querySelectorAll中获取按钮类型
- 如何在输入字段中的按钮的帮助下打开日历,该字段的类型为“=”;日期”;
- 如何将具有文本类型值的var放入jQuery函数中
- javascript解释器如何理解变量的数据类型
- 可变大小的JavaScript字符串如何成为基元类型
- AngularJS指令只识别双向绑定类型
- 在<输入类型=“;文件“/>
- 从查询字符串参数推断出正确的数据类型
- 未捕获的类型错误:无法读取属性'删除'的未定义
- 为什么不'我们在javascript中使用函数参数的数据类型
- Javascript 可选类型提示
- 可以<脚本类型=“;text/javascript”>window.location=“/"</
- 什么时候在流中的类型别名上使用接口
- 多态匿名函数类型别名
- 类型错误:对函数别名的非法调用