如何在抽象父 class 中创建通用方法来实现打字稿?
how make a generic method in a abstract parent class for implementation typescript?
在 TypeScript 中实现这一点的最佳和(正确)方法是什么。
$Foo.getInstance('uid')
应该 return FooInstance
基于实现?
我想抽象地 class Entity
一个从池中获取实例的方法,
对于 return 实施的 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');
所以这里的例子:
const instance = $Foo.getInstance('uid')
应该是 FooInstance
;
但它实际上 EntityInstance
是正确的!
所以我尝试将此方法 getInstance
更改为类似的方法。
getInstance <t=this>(uid: string ): InstanceType<this['Instance']> {
return this.instances[uid]
}
它工作正常!:) 但出现了一些错误类型。
我是 ts 文档的菜鸟,我可以做些什么改变来使这个逻辑正常工作。
我知道 ts 很强大,但我不确定如何在我的 ide.
最小的生殖演示typescript
我希望 myInstance.__foo2;
不会产生错误。
您可以尝试将 Entity
中的输入更改为以下内容:
abstract class Entity {
abstract Instance: new () => EntityInstance;
instances: Record<string,
InstanceType<this["Instance"]> | undefined
> = {};
}
Instance
属性 是一个 constructor that returns an EntityInstance
(or a subtype of it). And the instances
property type depends on the type of Instance
; by using polymorphic this
,我们说 Entity
的任何子类 instances
属性 将取决于同一子类中 Instance
的类型。
这为您提供了您正在寻找的行为,至少对于示例代码而言:
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
请注意,在子类本身内部使用多态 this
类型可能会有点麻烦:
class Foo extends Entity {
Instance = FooInstance;
constructor() {
super();
this.instances.abc = new FooInstance(); // error!
this.instances.abc = new this.Instance(); // error!
}
}
我不确定你是否需要做这样的事情,但是尝试在 Foo
内的 this.instances
上设置 属性 失败,因为编译器不知道是什么this
将是如果有人出现并继承 Foo
。它将 this
视为未指定的泛型类型,并且无法真正验证任何特定值是否可分配给它。在这种情况下,您可能需要使用 type assertions 来抑制错误。
另一种方法是使 Entity
成为 generic class,其中类型参数 T
对应于子类中 EntityInstance
的特定子类型:
abstract class Entity<T extends EntityInstance> {
abstract Instance: new () => T;
instances: Record<string, T | undefined> = {};
}
任何特定的子类都需要指定 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
在 TypeScript 中实现这一点的最佳和(正确)方法是什么。
$Foo.getInstance('uid')
应该 return FooInstance
基于实现?
我想抽象地 class Entity
一个从池中获取实例的方法,
对于 return 实施的 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');
所以这里的例子:
const instance = $Foo.getInstance('uid')
应该是 FooInstance
;
但它实际上 EntityInstance
是正确的!
所以我尝试将此方法 getInstance
更改为类似的方法。
getInstance <t=this>(uid: string ): InstanceType<this['Instance']> {
return this.instances[uid]
}
它工作正常!:) 但出现了一些错误类型。 我是 ts 文档的菜鸟,我可以做些什么改变来使这个逻辑正常工作。 我知道 ts 很强大,但我不确定如何在我的 ide.
最小的生殖演示typescript
我希望 myInstance.__foo2;
不会产生错误。
您可以尝试将 Entity
中的输入更改为以下内容:
abstract class Entity {
abstract Instance: new () => EntityInstance;
instances: Record<string,
InstanceType<this["Instance"]> | undefined
> = {};
}
Instance
属性 是一个 constructor that returns an EntityInstance
(or a subtype of it). And the instances
property type depends on the type of Instance
; by using polymorphic this
,我们说 Entity
的任何子类 instances
属性 将取决于同一子类中 Instance
的类型。
这为您提供了您正在寻找的行为,至少对于示例代码而言:
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
请注意,在子类本身内部使用多态 this
类型可能会有点麻烦:
class Foo extends Entity {
Instance = FooInstance;
constructor() {
super();
this.instances.abc = new FooInstance(); // error!
this.instances.abc = new this.Instance(); // error!
}
}
我不确定你是否需要做这样的事情,但是尝试在 Foo
内的 this.instances
上设置 属性 失败,因为编译器不知道是什么this
将是如果有人出现并继承 Foo
。它将 this
视为未指定的泛型类型,并且无法真正验证任何特定值是否可分配给它。在这种情况下,您可能需要使用 type assertions 来抑制错误。
另一种方法是使 Entity
成为 generic class,其中类型参数 T
对应于子类中 EntityInstance
的特定子类型:
abstract class Entity<T extends EntityInstance> {
abstract Instance: new () => T;
instances: Record<string, T | undefined> = {};
}
任何特定的子类都需要指定 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