以Typescript克隆对象,从Flow迁移

时间:2018-09-27 03:40:59

标签: javascript node.js typescript functional-programming flowtype

从本质上讲,我需要一个函数来克隆(即Deepcopies)共享某些公共属性的对象。 “公共属性”实质上只是一个用于操作的名为op的标签。所以以前我有一些使用Flow输入的代码:

export function cloneExpr<E: Expr>(exp: E): E {
    if (exp.op === POINT) {
        return ((expr.makePoint(exp.p, exp.x, exp.y):any):E);
    } ... etc
}

其中ExprPointLine等一堆东西的结合,所有这些东西都具有此op字段。强制播报有些丑陋,但至少可以奏效。也就是说,如果我cloneExpr键入了Point的对象,则返回对象的键入是Point,而无需提供更多的键入信息。

现在,我想迁移到Typescript,但遇到很多麻烦。强制广播的return ((exp as any) as Point)是在真空中工作的,但是我的类型防护不断丢失信息,因此,例如,在没有通过输入检查的情况下,我实际上无法从Point x获取字段exp 。为了使Typeguard正常工作,我尝试了各种函数类型的变体,例如:

function cloneExpr<T extends Expr>(exp: T): T

其中ExprPoint | Line类似。

function cloneExpr<T extends IsExpr>(exp: T): T

其中IsExpr是我定义的一个接口,其中只有一个op字段。

function cloneExpr(exp: Expr): Expr

我尝试过的

,但是显然我永远也不会得到正确的输入类型。

所以我没有得到类型保护,或者返回类型不是我输入的特定类型。我也尝试过使用Interfaces重新定义对象,然后提供用户定义的typeguard,但没有,但无济于事。

在Typescript中执行此操作的正确方法是什么?多谢。

1 个答案:

答案 0 :(得分:2)

在测试exp时无法将EPoint缩小到exp.op === POINT(或类似的东西)将由this suggestion解决。同时,通过将参数复制到类型为Expr的局部变量中,可以实现与Flow相同的类型安全性:

export function cloneExpr<E extends Expr>(exp: E): E {
    const exp1: Expr = exp;
    if (exp1.op === POINT) {
        return expr.makePoint(exp1.p, exp1.x, exp1.y) as any as E;
    }
    // ...
}