类到实例注册表键入打字脚本



我正在尝试将类用作注册表方法的输入值,其中返回值是该实例的缓存实例。 但是我没有找到使这种类型安全的方法。

我想要的是这样的东西:

class MyRegistry {
getInstance<T, C extends Class<T>>(cls: C): T;
}
let x: MyThing = registry.getInstance(MyThing);

有没有办法做到这一点?我知道有一些方法可以键入 newables,但我找不到使返回值具体的方法。

参数类型应描述作为参数传递的类的构造函数。这可以使用通用接口来实现:

interface Class<T> {
new (...args: any[]): T;
}
class MyRegistry {
getInstance<T>(param: Class<T>): T {
// do your magic
}
}

你可以在这里看到它的工作。

如果您需要使用子类 C,当然可以通过以下方法轻松扩展:

class MyRegistry {
getInstance<T, C extends T>(param: Class<C>): T {
// do your magic
}
}

您需要使用构造函数签名使编译器从构造函数中提取实例类型:

class MyRegistry {
getInstance<T>(cls: new (...args: any[])=> T): T {
return null as any;
}
}
class MyThing { private x: number }
let registry = new MyRegistry();
let x = registry.getInstance(MyThing); // inffered as MyThing

你可以考虑这样的事情:

class Class {}
class ClassY extends Class {}
class MyRegistry<T extends typeof Class> {
#reg = new Map<T, InstanceType<T>>()
getInstance<U extends T>(cls: U) { return this.#reg.get(cls) as InstanceType<U> }
setInstance(u: InstanceType<T>) { this.#reg.set(u.constructor as T, u) }
}
const r = new MyRegistry()
const x = r.getInstance(Class) // x: Class
const y = r.getInstance(ClassY) // y: ClassY

最新更新