Typescript 如何使约束强制泛型类实例适应给定接口?

Typescript 如何使约束强制泛型类实例适应给定接口?,typescript,Typescript,有此代码: 接口类{ 新(…args:any[]):any; } 类包装器{ asInterface():I{//这是约束应该去的地方 返回undefined作为any作为I;//这不重要 } } 界面{ 起飞():无效; } 接口车{ drive():void; } F35B类{ 起飞(){ 控制台日志(“进行垂直起飞”); } 射击(){ console.log('bang-bang'); } } const w=新包装器(); 常量平面=w.A接口();//这应该过去 const car=

有此代码:

接口类{
新(…args:any[]):any;
}
类包装器{
asInterface():I{//这是约束应该去的地方
返回undefined作为any作为I;//这不重要
}
}
界面{
起飞():无效;
}
接口车{
drive():void;
}
F35B类{
起飞(){
控制台日志(“进行垂直起飞”);
}
射击(){
console.log('bang-bang');
}
}
const w=新包装器();
常量平面=w.A接口();//这应该过去
const car=w.a接口();//这不应该
如何在接口方法上设置约束,使我成为构造函数C实例的扩展


当然,
InstanceType extends I
表达式与typescript不兼容,但这就是问题的关键所在。

Typescript实现这一点的方法不是将
I
作为通用参数传递,而是将赋值注释为
常量平面:平面=…
,如果不可赋值,则让Typescript出错

我还做了另外两个改变。首先,您的
接口需要是实例类型的泛型接口,否则
new
将不会返回正确的类型。第二,您的
包装器
需要在运行时接受包装的构造函数,它不能只调用泛型参数
C
上的
new
,因为泛型在运行时会被擦除

所以我认为最终的结果会是这样的:

interface Class<I> {
    new(...args: any[]): I;
}

class Wrapper<C extends Class<InstanceType<C>>> {
  constructor (private Wrapped: C) {} // <----  `C` is inferred
  create () { return new this.Wrapped() }
}

interface Plane {
    takeoff(): void;
}

interface Car {
    drive(): void;
}

class F35B {
    takeoff() {
        console.log('doing vertical takeoff');
    }
    shoot() {
        console.log('bang bang');
    }
}

const w = new Wrapper(F35B); // <---- Pass constructor at runtime

const plane: Plane = w.create();  // OK

const car: Car = w.create(); // Error
//    ~~~
// Property 'drive' is missing in type 'F35B' but required in type 'Car'

接口类{
新(…args:any[]):I;
}
类包装器{

构造函数(private Wrapped:C){}/我刚刚发现,使用三元类型表达式,可以在返回类型处约束它,如下所示:

interface Class<I> {
    new(...args: any[]): I;
}

class Wrapper<C extends Class<InstanceType<C>>> {
  constructor (private Wrapped: C) {} // <----  `C` is inferred
  create () { return new this.Wrapped() }
}

interface Plane {
    takeoff(): void;
}

interface Car {
    drive(): void;
}

class F35B {
    takeoff() {
        console.log('doing vertical takeoff');
    }
    shoot() {
        console.log('bang bang');
    }
}

const w = new Wrapper(F35B); // <---- Pass constructor at runtime

const plane: Plane = w.create();  // OK

const car: Car = w.create(); // Error
//    ~~~
// Property 'drive' is missing in type 'F35B' but required in type 'Car'

接口类{
新(…args:any[]):any;
}
type Subtype=InstanceType扩展I?I:从不;
类包装器{
asInterface():InstanceType扩展I?I:never{//约束是结果表达式
//@ts忽略
return undefined;//这不重要
}
}
界面{
起飞():无效;
}
接口车{
drive():void;
}
F35B类{
起飞(){
控制台日志(“进行垂直起飞”);
}
射击(){
console.log('bang-bang');
}
}
const w=新包装器();
常量平面=w.A界面();
飞机起飞();
const car=w.a接口();
汽车起飞;
//^^^^^^^^类型上不存在属性“takeoff”

Quoting我如何在
a接口
方法上设置一个约束,使得
I
是构造函数
C
实例的扩展?——类的构造函数位于类的静态端。有像
takeoff
这样的方法位于接口或类的实例端(交互也没有静态的一面,实际上根本没有侧面)。因此,接口
平面
和类
F35B
的构造函数中不会有重叠。尽管与类的接口约束可能会起作用(而不是构造函数)。最后,expressioin
InstanceType extends I
与typescript兼容。它只需要是返回类型的三元表达式的一部分,如我的回答中所述。非常感谢您的时间和努力。遗憾的是,我问题的关键是在方法级别对接口类型进行参数化。因此,您的回答无效对于我的用例