[英]Typescript - Store Class Type As Variable In Order to Create Objects From It Or Other Equivalent Functionality
Preface - I have looked at similar posts to this one on SO, but the answers did not seem applicable.前言 - 我在 SO 上看过与此类似的帖子,但答案似乎并不适用。
I have an abstract class with the following method (simplified):我有一个具有以下方法(简化)的抽象类:
playAnimation() {
let animator = this.createAnimator(this.animatorData)
await animator.animate()
}
Create animator has the following definition inside that abstract class: Create animator 在该抽象类中具有以下定义:
abstract createAnimator(animatorData: Object): Animator
A subclass might implement createAnimator
like this:一个子类可能会像这样实现
createAnimator
:
createAnimator(animatorData: StandardAnimatorData) {
return new RiverAnimator(animatorData.addMessage, animatorData.assetsDir)
}
or like this:或者像这样:
createAnimator(animatorData: StandardAnimatorData) {
return new BridgeAnimator(animatorData.addMessage, animatorData.assetsDir)
}
As you can see - both of the sub classes's implementations of createAnimator
are roughly identical, except for the type of the Animator
being returned.如您所见 -
createAnimator
两个子类的实现大致相同,除了返回的Animator
的类型。
Sidenote BridgeAnimator
and RiverAnimator
both implement the Animator
interface, but if the solution requires Animator
to be an abstract class, I can change it. BridgeAnimator
和RiverAnimator
都实现了Animator
接口,但是如果解决方案要求Animator
是抽象类,我可以更改它。
Is there a way to move createAnimator
into the abstract base class?有没有办法将
createAnimator
移动到抽象基类中?
Ideally the abstract class would have an abstract variable that is the type of the class that createAnimator
should return.理想情况下,抽象类应该有一个抽象变量,它是
createAnimator
应该返回的类的类型。 Subclasses would merely implement that variable.子类只会实现该变量。 Then
createAnimator
would use that variable to return the proper type of Animator
.然后
createAnimator
将使用该变量返回正确类型的Animator
。
Yes, you can do something like this (I made one big code snippet so I can verify that everything compiles):是的,你可以做这样的事情(我做了一个大的代码片段,所以我可以验证一切都编译):
interface Animator {
animate(): Promise<void>;
}
class RiverAnimator implements Animator {
async animate() { }
constructor(addMessage: unknown, assetsDir: unknown) { }
}
class BridgeAnimator implements Animator {
async animate() { }
constructor(addMessage: unknown, assetsDir: unknown) { }
}
interface StandardAnimatorData {
addMessage: unknown;
assetsDir: unknown;
}
// Common interface for the constructor functions RiverAnimator and BridgeAnimator
interface AnimatorConstructor {
new(addMessage: unknown, assetsDir: unknown): Animator;
}
abstract class AbstractOuterClass {
abstract animatorConstructor: AnimatorConstructor;
animatorData: StandardAnimatorData;
createAnimator(data: StandardAnimatorData) {
return new this.animatorConstructor(data.addMessage, data.assetsDir);
}
async playAnimation() {
let animator = this.createAnimator(this.animatorData);
await animator.animate();
}
}
class SubOuterClass1 extends AbstractOuterClass {
animatorConstructor = RiverAnimator;
}
class SubOuterClass2 extends AbstractOuterClass {
animatorConstructor = BridgeAnimator;
}
But it's not clear to me that this is any better than implementing createAnimator
in SubOuterClass1
and SubOuterClass2
.但我不清楚这是否比在
SubOuterClass1
和SubOuterClass2
实现createAnimator
更好。
Another approach is to use the power of generics:另一种方法是使用泛型的力量:
declaration:宣言:
createAnimator<T extends Animator>(
type: { new(addMessage: unknown, assetDir: unknown): T },
animatorData: StandardAnimatorData
): T {
return new type(animatorData.addMessage, animatorData.assetDir);
}
invocation:调用:
let animator = this.createAnimator(BridgeAnimator, animatorData);
await animator.animate();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.