javascript - 流程中的未细化类型转换,在对象(以及所述对象的数组)中使用嵌套类型

标签 javascript flowtype

我们考虑以下代码片段,其中我有两种对象类型。第二种类型是第一种类型的更精致版本:

/* @flow */

type A = {|
  value: string | number,
|}

type B = {|
  value: number,
|}

const b:B = { value: 2 };
const a:A = { value: 2 }; //works.

const z:A = b; //fails, but for javascript it is exactly the same as line above

这在最后一行失败,因为流程告诉我“数字”与“字符串”不兼容。但是类型是“并集”而不是交集,所以它应该有效吗? (只是为了再次使用该类型,我必须再次改进它)。

在我的真实代码中,我实际上拥有所述对象的数组,并且对象包含更多数据,因此手动复制对象并不是可行的方法。

<小时/>

我意识到这是一个抽象的概述,但最终我希望有一个函数,它接受“精炼的 A”并返回“A”,即一个更真实的示例:

type A = {|
  value: string | number,
  value2: string,
|}

function foo(input: $ReadOnlyArray<{| ...$Exact<A>, value: number|}>): Array<A> {
  return input.filter(v => v.value === 2);
}

有没有更好的方式来表达“这个函数采用 X 类型的精炼版本”。

最佳答案

Depth Subtyping 中的最后一段文档页面有点解释了这里发生的事情(无可否认,文档有点糟糕)。

By default, object properties are invariant, which allow both reads and writes, but are more restrictive in the values they accept.

现在,A 上的 value 属性默认情况下是不变的。这意味着它接受其给定类型,非常明确。您不能为其分配 numberstring 的内容,只能为其分配 number | 的内容。字符串。任何具有比 number | 或多或少明确的给定类型的东西字符串不会被接受:

type Ambiguous = {|
  value: string | number,
|};

type Specific = {|
  value: number,
|};

const myAmbiguous: Ambiguous = ({ value: 1 }: Specific); // error!

对此我们可以做的一件事是将属性标记为协变,如同一段落中前面提到的:

The plus sign indicates that the [...] property is “covariant.” Using a covariant property allows us to use objects which have subtype-compatible values for that property.

这应该允许我们为我们的属性分配更具体的类型(在本例中为number):

type Ambiguous = {|
  +value: string | number,
|};

type Specific = {|
  value: number,
|};

const myAmbiguous: Ambiguous = ({ value: 1 }: Specific); // all good

但请注意,value 现在是只读的:

myAmbiguous.value = 3; // error!
         // ^ Cannot assign `3` to `myAmbiguous.value` 
         //   because property `value` is not writable.

我建议您阅读有关深度子类型的页面的其余部分以及 Type Variance 上的页面。 .

关于javascript - 流程中的未细化类型转换,在对象(以及所述对象的数组)中使用嵌套类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55314515/

相关文章:

javascript - Flow.js 从节点模块推断返回类型

javascript - Angularjs Post 不向 Spring JWT 发送 header

javascript - 如何更改 javascript 中的宽度属性?

javascript - 根据 anchor 目标在文档中的顺序对列表元素进行排序

reactjs - React 默认 props 被忽略

vim - 在 Vim 状态行中显示多行流错误?

javascript - 如何使用jCarousel放大 slider ?

javascript - 浏览器问题 :Branching Select Drop Down Not Supporting in IE 7 or 8

javascript - 你能用 Facebook 的 Flow 注释那些没有用 ES6 class 关键字定义的类吗?

javascript - 混合正常和 Flow -'type' 导入