【问题标题】:What does spread operator in type declaration do in Flow?类型声明中的扩展运算符在 Flow 中的作用是什么?
【发布时间】:2019-03-04 16:55:45
【问题描述】:

如果我有两个形状部分匹配的对象,例如

const point2d = { x: 0, y: 0 };
const point3d = { x: 0, y: 0, z: 0 };

那么 Flow 中的有效类型声明将是

type Point2D = { x: number, y: number };
type Point3D = Point2D & { z: number };

起初,我尝试使用对象扩展运算符,但很快就遇到了问题,因为像这样的符号

type Point3D = { ...Point2D, z: number };

作为有效传递但未达到目标,因为最终Point3D 类型中缺少xy 属性。

例如,我可以使用扩展符号来做到这一点(这是错误的):

type Point2D = { x: number, y: number };
type Point3D = { ...Point2D, z: number };

const point2d: Point2D = { x: 0, y: 0 };
const point3d: Point3D = { y: 0, z: 0 }; // No errors

但不能错过带有类型交集符号的对象声明中的x 属性:

type Point2D = { x: number, y: number };
type Point3D = Point2D & { z: number };

const point2d: Point2D = { x: 0, y: 0 };
const point3d: Point3D = { y: 0, z: 0 }; // Cannot assign object literal to `point3d` because property `x` is missing in object literal [1] but exists in `Point2D` [2].

请注意,这两种情况都不是精确的形状。

在这种情况下,流在传播符号的情况下的行为是故意的吗?我错过了什么吗?

【问题讨论】:

  • this question重复。
  • 嗯,这绝对是should 做你说的。是什么让你相信事实并非如此?
  • 当然,但我的问题不在point2d.z,而是在point3d.x。请注意,您在示例中使用了正确的“&”符号,而我的问题是关于类型声明中的扩展运算符。
  • 哦,是的,很抱歉,我给你发错了例子。 Here's 正确的。这里的要点是,如果 x 未包含在类型 Point3D 中,则此示例中的第 7 行将出错。
  • 用两个例子扩展了这个问题,我希望 Flow 的行为相同,但它不同,我不明白为什么。所以我发现,当我直接引用Point3D 类型的对象的属性时,并且该类型以两种方式中的任何一种方式声明时,Flow 都会正确警告不存在的属性等。但是当我声明一个对象时,这两种情况会带来不同的结果。我通读了有关确切对象类型的文档,这很好,但在我的情况下,两种情况下的形状都不准确。我完全迷路了。

标签: flowtype


【解决方案1】:

this issue

简而言之,您可以通过使您的对象精确来解决基本上所有这些类型的问题。一般来说,我发现在将对象类型设置为精确时,您会更轻松地使用它们,除非您出于某种原因真的不希望它们精确。此外,$ReadOnly(如果适用)。 Try

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 2014-10-27
    • 2023-03-17
    • 2020-05-15
    相关资源
    最近更新 更多