打字稿条件继承

时间:2021-01-21 18:22:27

标签: javascript typescript three.js

目标是创建一个可以扩展不同类的原型。 我需要创建一个扩展 Mesh 或 Points of THREE.js 的类。对于这两种情况,我创建的子类都是相同的。不能是接口。

class PointsElement extends THREE.Points {
  public name: string
  protected width: number
  protected height: number

  constructor (protected target: THREE.Scene | THREE.Group, protected properties: IElementProperties) {
    super()
    this.name = this.properties.name
    AutoBind(this)
  }

  public async preload () {
  }

  public async show () {
    this.target.add(this)
  }

  public async hide () {
    this.target.remove(this)
  }
}

class MeshElement extends THREE.Mesh {
  public name: string
  protected width: number
  protected height: number

  constructor (protected target: THREE.Scene | THREE.Group, protected properties: IElementProperties) {
    super()
    this.name = this.properties.name
    AutoBind(this)
  }

  public async preload () {
  }

  public async show () {
    this.target.add(this)
  }

  public async hide () {
    this.target.remove(this)
  }
}

我想要做的是通过排除'Element'来减少代码,因为MeshElement和PointsElement中的主体是相同的,但是这些类中的每一个都扩展了不同的类

1 个答案:

答案 0 :(得分:1)

它有点快速和肮脏,但希望你能理解我所说的工厂模式是什么意思。

你所描述的只是一种做工厂的方式,而不是唯一的。

enum Geometrics {
  Mesh = "Mesh",
  Points = "Points"
}

class Element {
  public isElement = true;
}

class Mesh extends Element {
  public type = Geometrics.Mesh;
}

class Point extends Element {
  public type = Geometrics.Points;
}

class GeometricsFactory<T extends Geometrics> {
  private shapesMap = new Map<Geometrics, typeof Mesh | typeof Point>([
    [Geometrics.Mesh, class Shape extends Mesh {}],
    [Geometrics.Points, class Shape extends Point {}]
  ]);

  constructor(private type: Geometrics) {}

  public getShape(): T extends Geometrics.Mesh ? typeof Mesh : typeof Point {
    const shape = this.shapesMap.get(this.type);
    if (shape) {
      return <T extends Geometrics.Mesh ? typeof Mesh : typeof Point>shape;
    }
    throw new Error(`Invalid shape type ${this.type}`);
  }
}

const MyMesh = new (new GeometricsFactory<Geometrics.Mesh>(Geometrics.Mesh).getShape())();
console.log(MyMesh.type);

const MyPoints = new (new GeometricsFactory<Geometrics.Points>(Geometrics.Points).getShape())();
console.log(MyPoints.type);