流程中的结构子类型可能会导致信息丢失:
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)
(此代码非常糟糕,因为它执行可见的突变。仅用于说明目的。)
我已经读过行多态是一种避免信息丢失而不会危及类型安全的概念。
有没有办法实现与子类型多态相同?
[编辑]
为了满足更多观众的需求,我简要介绍了一些有些可怕的术语:
答案 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.
另外,之前我还没有听说过行多态,所以我去查了一下。在查找时,我已经阅读了几个似乎表明行多态不是子类型的东西。 1,2,3。
要扩展这个答案,并澄清为什么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以及它与函数参数,对象等的关系。
相关部分是: