流类型注释:为什么`ClassName< {}>`?

时间:2017-10-08 20:16:12

标签: javascript generics react-native flowtype

使用react-native init AwesomeProject创建一个新的React-Native项目,在生成的App.js中,我对此类声明中的<{}>感到困惑:

export default class App extends Component<{}> {

最终我发现<{}>Class Generic的Flow类型注释。

我熟悉generic types in Java并了解它们的用处。

但是,我正在努力理解Flow注释的目的。它完成了什么?据我所知,它验证App类的类型为Object。虽然这似乎是多余的,但如果是这种情况,那么我希望它会像react-native source一样写成<Object>,在:

class AnimatedComponent extends React.Component<Object> {

我能找到解释这种类型检查需求的唯一原因是MDN documentation for extends

  

扩展名的.prototype必须是Object或null。

<{}><Object>的简写吗?如果是这种情况,那么它似乎可以与使用实际字符串代替指定string的类型注释相媲美,这似乎是错误的。例如:

// @flow
function concat(a: string, b: string) {
    return a + b;
}
// as compared to -->
// @flow
function concat(a: "foo", b: "bar") {
    return a + b;
}
  1. <{}>注释的目的是什么?它对代码的验证是什么?
  2. <{}>是否等同于<Object>
  3. 我误解了什么吗?
  4. 谢谢!

1 个答案:

答案 0 :(得分:1)

Objects (and functions) in Flow are structurally typed。这就是说,匹配{...}类型的所有属性和类型的对象是它的子类型。在{}的情况下,这包括所有真实对象(因此禁止数组和文字),实际上Object === {}

string的示例根本不同,因为像a: "foo"这样的文字类型那些字符串实例,即"fo"不是子类型"foo"

至于泛型类型检查器特有的Component泛型的实际目的,实际上你可以完全省略泛型,因为它们可以从属性类型中推断出来。第一个通用参数是props的类型,第二个是state的类型。 See the docs