时间:2017-09-01 01:49:53

标签: flowtype

我试图使用流量0.53.1。你能帮我解释一下这种奇怪的行为吗?

此代码示例:

/* @flow */

type AnySupportedType =
  | AnySupportedPrimitive
  | AnySupportedObject
  | AnySupportedArray;
type AnySupportedArray = Array<AnySupportedType>;
type AnySupportedObject = { [string]: AnySupportedType };
type AnySupportedPrimitive = boolean | number | string | void;

type DataID = string
type Data = {
  id: DataID
}

const y: Data = { id: "123" }
const x: AnySupportedType = y;

呈现此错误:

17: const x: AnySupportedType = y;
                                ^ object type. This type is incompatible with
17: const x: AnySupportedType = y;
             ^ union: AnySupportedPrimitive | AnySupportedObject | AnySupportedArray

Link以flow.org基于网络的示例来玩。

2 个答案:

答案 0 :(得分:1)

实际上,这与可变性有关。 Flow不能允许此代码,因为您可以编写x.id = 5(在适当的类型细化之后),因为AnySupportedType类型允许您设置任何支持的类型,包括number作为属性。

要解决此问题,您需要使对象属性协变,从而有效地使它们成为只读:

type AnySupportedObject = { +[string]: AnySupportedType };

请注意添加+

执行此操作后,Flow会允许原始分配,但会阻止您在x上设置属性。

查看try上的完整示例。

请参阅https://flow.org/blog/2016/10/04/Property-Variance/

答案 1 :(得分:0)

答案是Flow有两种输入Objects的方法。一,您的AnySupportedObject将对象视为字典,您可以通过任意键找到项目(类似于Map<string, whatever>

另一种方式是作为记录,其中有一组特定的已知密钥,每个密钥可以指向其自己的值类型(例如,{a: number, b: string}

这两种类型具有非常不同的含义,但通常任何一种都可以应用于特定对象。类型系统使它们保持不同,并强制您以某种方式处理对象,以避免生成类型错误。