I'm trying to build an extension system with TypeScript. This system works as long as the extendable classes don't inherit from each other.
Here is a simplified version for this inheritance problem:
class ExtensionHost {
addExtension(extension: Extension<typeof this>): void {}
}
class Extension<T> {}
class Object3D extends ExtensionHost {}
class Cube3D extends Object3D {}
class CubeExtension extends Extension<Cube3D> {}
class Object3DExtension extends Extension<Object3D> {}
const cubeExt = new CubeExtension();
const objectExt = new Object3DExtension();
const cube = new Cube3D();
const object = new Object3D();
cube.addExtension(cubeExt); // OK
cube.addExtension(objectExt); // Problem 1: should error, but doesn't
object.addExtension(objectExt); // OK
object.addExtension(cubeExt); // Problem 2: should error, but doesn't
The class Object3D is extendable. And the class Cube3D inherits this functionality from the Object3D. Yet I want to prevent it from extending any Extension that does not directly match its own class.
Problem 1: the cube should not be extendable with a Extension<Object3D>. By hovering over the cube.addExtension(objectExt) it gives me the call signature of Object3D.addExtension(extension: Extension<Object3D>).
Problem 2: the object should not be extendable with Extension<Cube3D>. Here it makes a bit more sense, because a Extension<Cube3D> is also a Extension<Object3D>. Yet it would still be nice to prevent it.
Question: Is there a way to type it in a way that those problems can be fixed on the type-level? Problem 2 is not that important.