我正在使用通用的Typescript接口,在该接口中,工厂类是使用特定类实例化的,并且具有负责创建该类的各种实例的方法。我似乎无法实现的理想类型接口如下:
class BaseModel { /* impl */ }
class Foo extends BaseModel { /* impl */ }
class Factory<T extends BaseModel> { /* impl */ }
let factory : Factory<Foo> = new Factory(Foo)
let fooInstance = factory.build() // returns type: `Foo`
但是,Factory<T>
在不损害返回类型或保持并行构造函数类型定义的情况下,我无法弄清楚如何获得实现此目标的声明。
如果我仅依赖于已声明的类给出的类型,则构建函数的返回类型始终为BaseClass
,另外,我必须使通用Factory<typeof Foo>
而不是Factory<Foo>
:
class BaseModel {
static classMethod() : string {
return 'i am class method'
}
hello() {
return 'hello world'
}
}
class Foo extends BaseModel {}
class Factory<T extends typeof BaseModel> {
private _modelClass : T
constructor(modelClass : T) {
this._modelClass = modelClass
}
build() {
return new this._modelClass()
}
echoClassMethod() {
console.log(this._modelClass.classMethod())
}
}
let factory : Factory<typeof Foo> = new Factory(Foo)
let fooInstance = factory.build() // Returns type `BaseClass` instead of `Foo`
但是,如果我想让工厂类型接口正常工作,则必须维护一个反映了的并行类型定义typeof BaseModel
,但应将其作为构造函数:
class BaseModel {
static classMethod() : string {
return 'i am class method'
}
hello() {
return 'hello world'
}
}
class Foo extends BaseModel {}
// Have to maintain a separate type that
// mirrors the class interface of my target class
type BaseModelConstructor<T extends BaseModel> = {
new(...args: any[]) : T
classMethod() : string
}
class Factory<T extends BaseModel> {
private _modelClass : BaseModelConstructor<T>
constructor(modelClass : BaseModelConstructor<T>) {
this._modelClass = modelClass
}
build() {
return new this._modelClass()
}
echoClassMethod() {
console.log(this._modelClass.classMethod())
}
}
let factory : Factory<Foo> = new Factory(Foo)
let fooInstance = factory.build() // Correctly returns type `Foo`
必须有更好的方法将atypeof X
转换为X
or反之亦然?
假设X
既是构造函数值的名称,又是实例类型的名称(这是在声明时发生的情况class X {...}
):
更新:
从TypeScript 2.8开始,有一个预定义的类型函数被调用InstanceType<>
,该函数采用类构造函数的类型,并使用条件类型推断而非查找来求值其实例的类型。因此,您现在可以使用typeof X
来开始X
使用InstanceType<typeof X>
。但是(typeof X)['prototype']
下面仍然有效。
要开始typeof X
使用X
,通常可以查找构造函数类型的prototype
属性typeof X
。例如,下面我带注释的返回类型build()
是T['prototype']
:
class Factory<T extends typeof BaseModel> {
private _modelClass : T
constructor(modelClass : T) {
this._modelClass = modelClass
}
// note the declared return type
build(): T['prototype'] {
return new this._modelClass()
}
echoClassMethod() {
console.log(this._modelClass.classMethod())
}
}
然后进行以下工作:
let factory = new Factory(Foo)
let fooInstance = factory.build() // Foo, as desired.
有帮助吗?祝好运!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句