TypeScript

时间:2016-11-13 15:20:06

标签: typescript

我正在尝试做我认为是多态this的“教科书”用例,但它无法正常工作,我无法理解这一点。想象一下,我有一些可复制的abstract基类,例如:

abstract class X {
    abstract clone(): this;
}

现在我想实现一个提供clone实现的基类:

class Y extends X {
    constructor(private x: number) { super() }
    clone(): this { return new Y(this.x + 1); }
}

当我这样做时,我收到一条错误Type Y is not assignable to type 'this'。我完全糊涂了。我想在这里传达的是类型约束,如果X的子类调用了它的clone方法,那么你将获得的东西的类型将与子类型相同。这不是多态this的确切含义吗?我在这里做错了什么?

Here is a link到TypeScript playground中的此代码。

2 个答案:

答案 0 :(得分:2)

我已经将artem的答案标记为正确的答案,因为他似乎是正确的,因此无法以100%安全的方式执行此操作。

但是,有一种方法可以让编译器强制执行我想要的类型约束。所以,我决定将这个答案包括在内,以防人们对它有用。我的方法的唯一缺点是它确实有点不安全,因为artem指出的原因,即有人可以扩展你的类而不提供clone的实现,并创建一个返回值不会真正的情况是你声称的。

我的解决方案是添加演员。同样,这一般是不安全的。但是,如果你从不延伸到课程,它就可以正常工作。所以我的解决方案是:

class Y extends X {
    constructor(private x: number) { super() }
    clone(): this {
        return new Y(this.x + 1) as this;
    }
}

您可以看到编译here的完整版本。

答案 1 :(得分:2)

不,就像现在的情况一样,它不是这种类型的受支持用例。具有this返回类型的方法应返回派生类的实例,即使此方法未在派生类中重写 - 请参阅code in this answer以获得证明这一点的示例。

换句话说,给定abstract clone(): this声明,即使Z没有覆盖clone本身,此代码也必须有效,但是您在clone中实施Y会破坏它

class Z extends Y {
    f() {
        let c: Z = this.clone();
    }
}

因此看起来this返回类型的方法应始终为return this

更新:我在github上找到了一个open issue这个用例,标记为“接受拉取请求”。我不确定他们是否真的打算支持它,或者计划以其他方式在他们的编译器中修复cloneNode