流程:不能将没有参数的对象类型分配给具有可选参数的对象类型

Flow: Object type with no parameter can't be assigned to object type with optional parameter

在使用 Flow 类型时,我认为将没有特定参数的类型的对象分配给具有可选参数的类型的变量应该没问题。事实并非如此。

请看下面的代码...

// @flow

type T1 = {
  +a: string,
  +b? : number,
};

type T2 = {
  +a: string,
}

const t2: T2 = {
  a: "Hello",
};

const v1 : T1 = t2;    // ERROR!!! (Why???)

const v2 : T1 = {      // THIS WORKS
  ...t2
};

因为在 T1 中 'b' 属性 是可选的,为什么 Flow 应该阻止我分配另一种类型,其中 'b' 被简单地省略了?这个限制似乎是不必要的,也没有帮助。

是否有人了解此行为背后的基本原理或可以指出一些解释它的文档。我已经通读了 Flow Objects 部分,但在那里什么也没找到:https://flow.org/en/docs/types/objects/

正如我在评论中所说 T1T2 是两种不同的类型,因为 T1 有一个可选的属性 b.

type T1 = {
  +a: string,
  +b?: number,
}

type T2 = {
  +a: string,
}

const t2: T2 = {
  a: "Hello",
};

const v1 : T1 = t2;

流量错误:

无法将 t2 分配给 v1,因为 属性 bT2 中缺失,但在 T1 中存在. 没错!

解决方案是使用 T2 中的 exact type

type T2 = {|
  +a: string,
|}

看看Exact object types

现在当你有 T2 作为确切的对象时,你可以说:

const v1 : T1 = t2; // THAT'S OK!

因为 t2 满足类型 T1 的最小表示。

FlowTry Example

离开

不精确的对象类型失败,因为 Flow 无法知道 属性 b 类型 T2 的对象将具有什么类型。例如,我们可以有 const bad_t2: T2 = { a: 'string', b: 'also string' }。这应该清楚地表明我们不能将bad_t2赋值给T1类型的变量,因为b是类型string,这与T1的定义冲突。但是,当 T2 精确时,Flow 可以保证 属性 b 不会出现在 T2 类型的对象上,因此不会与 [=14= 冲突].