为了账号安全,请及时绑定邮箱和手机立即绑定

使用继承的方法在深度克隆对象时保持精确键入

使用继承的方法在深度克隆对象时保持精确键入

RISEBY 2022-08-27 09:34:00
我的结构如下:export class InteriorElement {  private x: number;  public draw(canvas: CanvasRenderingContext2D): void {    throw Error('Draw Method not implemented yet');  }}export class Seat extends InteriorElement {  public draw(canvas: CanvasRenderingContext2D): void {   canvas.drawRect(this.x, 0, 20, 20);  }}我可以使用以下命令生成一个新对象:const seat: Seat = new Seat();seat.x = 5;能用座位的抽奖方法seat.draw(this.canvasContext);现在,为了避免一遍又一遍地修改同一个座位,我想深入复制这个元素。但是,与其将方法复制/粘贴给每个孩子,我宁愿只使用IntersideElement类。因此,我希望有一个功能(我们非常邀请您改进该函数),如下所示:public deepCopy(): InteriorElement {  const deepCopy: InteriorElement = new InteriorElement(this.id);  Object.keys(this).forEach((key: string) => {    if (typeof (this[key]) === 'object') {      return this.deepCopyObject(this[key]);    } else {      deepCopy[key] = this[key];    }  });  return deepCopy;}private deepCopyObject(any: any): object {  const deepCopy: object = new Object();  Object.keys(any).forEach((key: string) => {    if (typeof (any[key]) === 'object') {      return this.deepCopyObject(any[key]);    } else {      deepCopy[key] = any[key];    }  });  return deepCopy;}我现在可以使用一个简单的:seat.deepCopy();然而,问题在于这显然会返回一个InsideElement。所以这样做:const seat2: Seat = seat.deepCopy();seat2.draw(); 将导致“绘制方法尚未实现”错误。即使const是键入的,它也会收到一个InsideElement,所以从现在开始它将是一个。有没有办法为deepCopy提供泛型类型?像这样:const seat2: Seat = seat.deepCopy<Seat>();这将导致:public deepCopy<T>(): T {  const object: T = new T();  [...]}不幸的是,它抛出了:“T”仅指一种类型,但在这里被用作值 - 错误。我如何知道InsideElement.deepCopy()副本请求哪个子项?
查看完整描述

1 回答

?
智慧大石

TA贡献1946条经验 获得超3个赞

这里的核心问题是,您希望返回在超类上实现克隆函数,该超类返回正在复制的任何子类实例。


首先,您需要返回类型 ,这意味着该方法返回与实例相同的类型。this


其次,您希望调用与此类相同的构造函数。除非我弄错了,否则typescript不会让这变得容易。的类型只是 ,而不是您可能期望的类构造函数。但是,您可以以一种提供相当强大的类型安全性的方式强制使用它。someInstance.constructorFunction


class A {

  constructor(public data: string) { }


  deepCopy<

    // This generic argument will be the type of the class object

    // that this is an instance of. It must be a subclass of A.

    T extends typeof A

  >(): this {

    // Get the constructor as the constructor of some subclass of A.

    const constructor = this.constructor as T


    // Create the new instance as the same type as `this`.

    const newInstance = new constructor(this.data) as this


    // return the copy.

    return newInstance

  }

}


class B extends A {}


const b1 = new B('some data here')

const b2: B = b1.deepCopy() // works

操场


泛型参数表示函数中将是某个构造函数,该构造函数是 A 的子类。我们真的不在乎哪一个。T extends typeof AT


然后,我们可以简单地强制一些类型脚本无法推断的强制转换。


但是,这种类型安全性崩溃的地方是,如果子类具有不同的构造函数签名,这可能会中断,因为不知道如何调用它们。deepCopy


查看完整回答
反对 回复 2022-08-27
  • 1 回答
  • 0 关注
  • 96 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信