打字稿将类型`typeof Foo`转换为`Foo`

韦德·坦迪

我正在使用通用的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转换为Xor反之亦然?

贾卡尔兹

假设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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何正确地将 _foo 转换为 `Foo` 类型?

将* [] foo类型的变量转换为* [] bar

Swift:将Foo <String>转换为Foo <Any>

将Map <Long,List <Foo >>转换为List <Foo>

有什么办法可以将Box <Box <Foo + Send >>转换为Box <Box <Foo >>?

如何使用番石榴将MultiMap <Integer,Foo>转换为Map <Integer,Set <Foo >>?

Swift Combine:如何将`AnyPublisher <[Foo],*>`转换为`AnyPublisher <Foo,*>`?

将IEnumerable <foo>的列表转换为List <string>

如何在打字稿中将 json 对象转换为 ReadOnlyMap<string, Foo>

打字稿:将标记联合转换为联合类型

如何将Redis条目转换为打字稿类型?

将字符串转换为Foo(字符串类型)

打字稿类型转换

如何转换List <?将Foo>扩展到List <Foo>

如何将jQuery的$('#foo')转换为document.createElement创建的对象?

Java 8将Optional <Object>强制转换为long,int,String或Foo

如何将LiveData <List <Foo >>转换为LiveData <List <Bar >>?

如何将字符串foo [bar]转换为实际数组?

打字稿:使用将对象转换为其他类型。怎么样?还有instanceof或typeof?

将类型 'Map<string, string>' 转换为类型 '{ [key: string]: string; }' 在打字稿中

打字稿:将类型转换为json对象时,“类型缺少属性getName”

打字稿:将严格的原始类型强制转换为原始类型

从Foo **到void **的无效转换-为什么允许隐式类型转换为void *但不允许为void **?

打字稿:属性 'foo' 不存在于类型 'Foo | 酒吧'

转换.py文件时,出现UndefinedVariableError时,将df.query(“ foo = @ bar”)之类的行转换为.pyd文件

打字稿:将 HTMLElement 转换为节点

将“ this”从jquery转换为打字稿

打字稿-将json转换为接口

将反应函数转换为打字稿