[英]how make a generic method in a abstract parent class for implementation typescript?
What will be the best and (proper) approach to make this in TypeScript.在 TypeScript 中进行此操作的最佳和(正确)方法是什么。
$Foo.getInstance('uid')
should return a FooInstance
based on implementations? $Foo.getInstance('uid')
应该根据实现返回一个FooInstance
吗?
I want in the abstact class Entity
a method to get a instance from a pool, for return the implemented EntityInstance
.我想在抽象的 class
Entity
中提供一种从池中获取实例的方法,以返回实现的EntityInstance
。
abstract class Entity {
abstract Instance: Partial<typeof EntityInstance>;
instances: { [uid: string]: EntityInstance } = {};
getInstance (uid: string ) {
return this.instances[uid]
}
}
abstract class EntityInstance {
prop='';
}
class Foo extends Entity {
Instance = FooInstance // @implementation
}
class FooInstance extends EntityInstance {
}
const $Foo = new Foo();
// need return InstanceType<FooInstance>
const instance = $Foo.getInstance('uid');
So example here: const instance = $Foo.getInstance('uid')
should be a FooInstance
;所以这里的例子:
const instance = $Foo.getInstance('uid')
应该是FooInstance
; But it actually a EntityInstance
thats correct !但它实际上是一个
EntityInstance
那是正确的!
so i try change this method getInstance
to something like this.所以我尝试将此方法
getInstance
更改为这样的东西。
getInstance <t=this>(uid: string ): InstanceType<this['Instance']> {
return this.instances[uid]
}
It working:.) but make some error type, Am noob with ts documentations.它工作:.) 但会产生一些错误类型,我是新手,有 ts 文档。 what change i can made to make this logic work fine, I know ts is powerful.
我可以做些什么改变来使这个逻辑正常工作,我知道 ts 很强大。 but am not sure how to make this work fine for intelisence in my ide.
但我不确定如何使这项工作在我的 ide 中正常工作。
minimal reproductive demo typescript i want myInstance.__foo2;
最小再现演示typescript我想要
myInstance.__foo2;
not produce error.不产生错误。
You could try changing the typings in Entity
to the following:您可以尝试将
Entity
中的类型更改为以下内容:
abstract class Entity {
abstract Instance: new () => EntityInstance;
instances: Record<string,
InstanceType<this["Instance"]> | undefined
> = {};
}
The Instance
property is a constructor that returns an EntityInstance
(or a subtype of it). Instance
属性是一个构造函数,它返回一个EntityInstance
(或其子类型)。 And the instances
property type depends on the type of Instance
;而
instances
属性类型取决于Instance
的类型; by using polymorphic this
, we are saying for any subclass of Entity
the instances
property will depend on the type of Instance
in the same subclass.通过使用多态
this
,我们说对于Entity
的任何子类, instances
属性将取决于同一子类中Instance
的类型。
This gives you the behavior you're looking for, at least for the example code:这为您提供了您正在寻找的行为,至少对于示例代码:
class Foo extends Entity {
Instance = FooInstance;
}
class FooInstance extends EntityInstance {
__foo2 = 2;
}
const $Foo = new Foo();
$Foo.instances['myUid'] = new $Foo.Instance();
const myInstance = $Foo.instances['myUid'];
myInstance.__foo2; // okay
Note that polymorphic this
types can be a bit of a pain to work with inside the subclasses themselves:请注意,在子类本身内部使用
this
多态类型可能会有点麻烦:
class Foo extends Entity {
Instance = FooInstance;
constructor() {
super();
this.instances.abc = new FooInstance(); // error!
this.instances.abc = new this.Instance(); // error!
}
}
I'm not sure if you need to do something like this, but trying to set a property on this.instances
inside Foo
fails because the compiler doesn't know what this
will be if someone comes along and subclasses Foo
.我不确定您是否需要做这样的事情,但是尝试在
Foo
内部的this.instances
上设置属性失败,因为编译器不知道this
有人出现并继承Foo
会发生什么。 It treats this
like an unspecified generic type and is not really able to verify that any particular value is assignable to it.它将
this
视为未指定的泛型类型,并且无法真正验证任何特定值是否可分配给它。 In such cases you might need to use type assertions to suppress errors.在这种情况下,您可能需要使用类型断言来抑制错误。
Another approach is to make Entity
a generic class where the type parameter T
corresponds to the particular subtype of EntityInstance
in subclasses:另一种方法是使
Entity
成为通用 class ,其中类型参数T
对应于子类中EntityInstance
的特定子类型:
abstract class Entity<T extends EntityInstance> {
abstract Instance: new () => T;
instances: Record<string, T | undefined> = {};
}
Any particular subclass needs to specify what T
should be (which is a bit redundant), but then everything works... both inside and outside the subclass:任何特定的子类都需要指定
T
应该是什么(这有点多余),但随后一切正常......在子类内部和外部:
class Foo extends Entity<FooInstance> {
Instance = FooInstance;
constructor() {
super();
this.instances.abc = new FooInstance(); // okay
this.instances.abc = new this.Instance(); // okay
}
}
myInstance.__foo2; // still okay
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.