Typescript 如何使用“创建”创建类的新实例;这";从内部方法?

Typescript 如何使用“创建”创建类的新实例;这";从内部方法?,typescript,Typescript,我正在寻找一种从类方法中调用newthis的方法 class Example { fork() { return new this(); } } const x = new Example().fork(); // instance of example class Alpha extends Example {} const x = new Alpha().fork(); // expected instance of Alpha but is example 我假定您

我正在寻找一种从类方法中调用new
this
的方法

class Example {
  fork() {
    return new this();
  }
}

const x = new Example().fork(); // instance of example

class Alpha extends Example {}

const x = new Alpha().fork(); // expected instance of Alpha but is example

我假定您的意思是希望调用
newthis.constructor()
(请参阅)而不是
newthis()
,因为类的实例同时也是类构造函数的情况非常罕见。在运行时,这就是您所需要的


不幸的是,TypeScript中的
构造函数
的键入很混乱。有关详细信息,请参见,但主要问题是,由于子类构造函数可能需要与其超类构造函数不同的一组参数,如果
this.constructor
是强类型的,那么许多
class
层次结构将无法形成有效的子类型层次结构,因此将违反

因此,在TypeScript中,
构造函数
仅被键入为
函数
,因此
新建此.constructor()
将产生错误:

return new this.constructor(); // error!
// This expression is not constructable.
为了告诉编译器
this.constructor
是一个零参数构造函数,您必须使用如下类型断言:

class Example {
  fork(): this {
    return new (this.constructor as new () => this)()
  }
}
class Example2 {
  ['constructor']: new () => this
  fork(): this {
    return new this.constructor()
  }
}
或者向类中添加强类型的
构造函数
属性声明,如下所示:

class Example {
  fork(): this {
    return new (this.constructor as new () => this)()
  }
}
class Example2 {
  ['constructor']: new () => this
  fork(): this {
    return new this.constructor()
  }
}
这两种解决方案都适用于您介绍的示例用例:

const x = new Example().fork(); // Example
class Alpha extends Example { }    
const y = new Alpha().fork(); // Alpha
但这两种解决方案都不会阻止您对构造函数需要参数的子类的实例调用
fork()

class Blop extends Alpha {
  constructor(x: string) {
    super();
    console.log(x.toUpperCase());
  }
}
const z = new Blop("oops").fork(); // error at runtime!!
如果没有一个好的microsoft/TypeScript#3841解决方案,我认为这可能是你能得到的最好的解决方案



我假定您的意思是希望调用
新this.constructor()
(请参阅)而不是
新this()
,因为类的实例同时也是类构造函数的情况非常罕见。在运行时,这就是您所需要的


不幸的是,TypeScript中的
构造函数
的键入很混乱。有关详细信息,请参见,但主要问题是,由于子类构造函数可能需要与其超类构造函数不同的一组参数,如果
this.constructor
是强类型的,那么许多
class
层次结构将无法形成有效的子类型层次结构,因此将违反

因此,在TypeScript中,
构造函数
仅被键入为
函数
,因此
新建此.constructor()
将产生错误:

return new this.constructor(); // error!
// This expression is not constructable.
为了告诉编译器
this.constructor
是一个零参数构造函数,您必须使用如下类型断言:

class Example {
  fork(): this {
    return new (this.constructor as new () => this)()
  }
}
class Example2 {
  ['constructor']: new () => this
  fork(): this {
    return new this.constructor()
  }
}
或者向类中添加强类型的
构造函数
属性声明,如下所示:

class Example {
  fork(): this {
    return new (this.constructor as new () => this)()
  }
}
class Example2 {
  ['constructor']: new () => this
  fork(): this {
    return new this.constructor()
  }
}
这两种解决方案都适用于您介绍的示例用例:

const x = new Example().fork(); // Example
class Alpha extends Example { }    
const y = new Alpha().fork(); // Alpha
但这两种解决方案都不会阻止您对构造函数需要参数的子类的实例调用
fork()

class Blop extends Alpha {
  constructor(x: string) {
    super();
    console.log(x.toUpperCase());
  }
}
const z = new Blop("oops").fork(); // error at runtime!!
如果没有一个好的microsoft/TypeScript#3841解决方案,我认为这可能是你能得到的最好的解决方案



感谢您的广泛回复,这里有很多好的经验教训和技巧,我非常感谢您抽出时间整理这个答案。感谢您的广泛回复,这里有很多好的经验教训和技巧,我非常感谢您抽出时间整理这个答案。