流量的信息丢失与这种多态性固有的结构子类型有关吗?

时间:2017-09-14 19:57:08

标签: javascript polymorphism flowtype subtyping structural-typing

流程中的结构子类型可能会导致信息丢失:

type O = {x: number, y: number};
type P = {x: number, y: number, z: number}

function f(o: O) {
    return o.x * 2, o.y * 2, o;
}

const p: P = {x: 2, y: 3, z: 100};
const r = f(p);

r.z // type error (property not found)

(此代码非常糟糕,因为它执行可见的突变。仅用于说明目的。)

我已经读过行多态是一种避免信息丢失而不会危及类型安全的概念。

有没有办法实现与子类型多态相同?

[编辑]

为了满足更多观众的需求,我简要介绍了一些有些可怕的术语:

  • Polymorpishm 只是一个奇特的词,用于确定两种类型是否相同,即它使刚性类型系统更加灵活
  • 参数多态(流程中的泛型)指出两种类型总是等价的,因为类型根本不重要
  • 子类型多态性(流中的子类型)指出如果您可以从它们派生层次结构,则两种类型是等效的,即将子类型包含在其超类型下
  • 行多态类似于子类型,但解决了信息丢失问题(从技术上讲,不再存在子类型关系,因此它不是一种子类型)
  • 有界多态性指出两种类型仅用于特定目的,例如:平等,秩序,映射等。

1 个答案:

答案 0 :(得分:1)

关于我对Flowtype的了解,我很确定你的功能是问题。

如果你这样做:

function f<T: O>(o: T): T {
  o.x *= 2;
  o.y *= 2;
  return o;
}

r.z; // okay

这是因为有限的多态性。现在,身体类型在假设T是O的子类型的情况下进行检查。此外,呼叫站点之间不会丢失任何信息。 Read more about it here.

另外,之前我还没有听说过行多态,所以我去查了一下。在查找时,我已经阅读了几个似乎表明行多态不是子类型的东西。 123

要扩展这个答案,并澄清为什么OP功能不起作用,但我建议的那个将正常工作。 Ťhis is a nice reference as well but is specific to Java

具有以下功能:

function f(o: O) {
  return o.x * 2, o.y * 2, o;
}

该函数指定它显式查找类型为O的对象,而不是允许O的对象或O的子类型。在OPs函数中,我们将参数o向下转换为类型O,而不是使用泛型(这很糟糕)。处理此问题的正确方法是使用泛型来指定它可以是O的类型O或子类型,可以按如下方式完成:

function f<T: O> (o: T): T {
  o.x *= 2;
  o.y *= 2;
  return o;
}

Check out the docs on how flow handles generics以及它与函数参数,对象等的关系。

相关部分是:

  •   

    &#34;泛型允许您在添加约束时保留更具体的类型。通过这种方式,泛型上的类型充当“边界”。 link

  •   

    &#34;泛型有时允许您将类似参数中的类型传递给函数。这些被称为参数化泛型(或参数多态)。&#34; link