gpt4 book ai didi

javascript - 为什么 Flow 拒绝由并集的交集组成的元组?

转载 作者:行者123 更新时间:2023-11-29 15:22:58 27 4
gpt4 key购买 nike

在下面的代码中,我不明白为什么 Flow 会拒绝我的 kv元组。

// @flow

type String = {
type: "string",
value: string
};

type Number = {
type: "number",
value: number
};

type Value = Number | String;

type Foo = { foo: "bar" } & Value;

let obj: Foo = {
foo: "bar",
type: "number",
value: 42
};

let kv: [string, Foo] = ["obj", obj];

Flow 似乎成功地进行了类型检查 obj作为Foo , 但不希望我在 [string, Foo] 中使用它元组。

确实我收到以下错误:

23: let kv: [string, Foo] = ["obj", obj];
^ intersection type. This type is incompatible with
15: type Foo = { foo: "bar" } & Value;
^ union: Number | String

这是怎么回事?

最佳答案

不幸的是,“Try Flow”没有为您提供完整的类型错误跟踪。如果你去here然后单击“json”,您可以深入了解并了解有关正在发生的事情的更多信息。

问题:非确定性

可以将其视为继承问题。 Flow 试图确定 Foo 是什么类型。因为在 Foo 的声明中没有指明它是 { foo } & Number 还是 { foo } & String,所以 Flow 似乎天真地尝试同时应用这两者。

所以在第 23 行,流程说,“类型不是 Foo,因为我希望属性“类型”是“字符串”,“值”是类型“数字”。但是如果你切换它, Flow 仍然会报错。

这是我思考问题的另一种方式:

class String
class Number
class Value extends String || Number // <= unable to determine what Foo is extending
type Foo = { stuff } & Value // <== ...locked-in non-deterministic

在这种情况下,Flow 无法确定“Foo”扩展的是什么,但如果某个变量被分配了 Value 类型,则有一些逻辑来解析类型。但是……

创建 Foo 别名时,Value 仍然是不确定的,就像 Flow 试图锁定 Foo 一样。一旦您访问某个属性,Flow 就会抛出错误。

幸运的是,有两种简单的方法可以解决这个问题。

不相交的联合

第一个涉及名为 disjoint unions 的功能. Here's a working example .

type Foo = { foo: "bar" }

type String = Foo & {
type: "string",
value: string
};

type Number = Foo & {
type: "number",
value: number
};

type Value = Number | String;

let obj: Foo = {
foo: "bar",
type: "number",
value: 42
};

let kv: [string, Foo] = ["obj", obj]; // no errors!

为什么会这样?同样,假设您使用继承模式编写此代码:

class Foo;
class String extends Foo; // <== deterministic
class Number extends Foo; // <== deterministic
var Value = String | Number // <== enum of certain classes, so still deterministic

对象类型传播(未发布)

如果您获取 Flow 的最新主分支,还会有一个很酷的功能,即对象类型传播。 Here's an example :

// @flow (master branch)

type String = {
type: "string",
value: string
};

type Number = {
type: "number",
value: number
};

type Value = Number | String;

type Foo = { foo: "bar", ...Value }

let obj: Foo = {
foo: "bar",
type: "number",
value: 42
}; // no error!

let otherObj: Foo = {
foo: "bar",
type: 'string',
value: 'I am a string',
}; // no error!

关于javascript - 为什么 Flow 拒绝由并集的交集组成的元组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42039969/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com