hom*_*mam 3 javascript flowtype
似乎命名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)
Run Code Online (Sandbox Code Playgroud)
我需要从任何引用中删除泛型类型注释,以F<X, Y>在apply类型检查器的匿名函数的参数中键入.
这是违反直觉的.
[编辑:]但似乎Flow能够键入检查apply1调用,即使它无法键入检查apply1本身:
apply1(x => x * 2, 'a') // error: ^ string. This type is incompatible with
apply1(x => x * 2, 1) // works
Run Code Online (Sandbox Code Playgroud)
更普遍:
// 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)
Run Code Online (Sandbox Code Playgroud)
我必须X, Y从类型别名的参数中删除泛型类型注释,Apply以便对其进行类型检查.
这是预期的行为还是我错过了什么?
const apply1 = <X, Y>(f: F<X, Y>, x: X): Y => f(x)
Run Code Online (Sandbox Code Playgroud)
首先,正如注释中提到的@squint,F没有类型参数隐式意味着F<any, any>,这就是为什么apply0在你的例子中起作用.
那你为什么apply1会有错误呢?嗯,这是因为Flow不会推断出泛型.所以当你写的时候
const apply1 : <X, Y>(f: F<X, Y>, x: X) => Y = (f, x) => f(x)
Run Code Online (Sandbox Code Playgroud)
任务的右侧是
(f, x) => f(x)
Run Code Online (Sandbox Code Playgroud)
和Flow不能推断出这个箭头函数是多态的.所以你可以像这样在RHS中添加类型参数:
const apply1 : <X, Y>(f: F<X, Y>, x: X) => Y = <X, Y>(f: F<X, Y>, x: X): Y => f(x)
Run Code Online (Sandbox Code Playgroud)
这应该可以解决错误.但此时,左侧的类型注释不再是必需的.所以你可以简化它
const apply1 = <X, Y>(f: F<X, Y>, x: X): Y => f(x)
Run Code Online (Sandbox Code Playgroud)
Avik Chaudhuri写了一个关于类似堆栈溢出问题的简短解释,后者又链接到GitHub上的类似答案