抽象类中的Typescript静态方法可创建self的实例

时间:2018-09-26 08:21:15

标签: javascript typescript

假设我有

      <exclusions>
...
      </exclusions>

我希望能够创建一个静态方法来创建最终类的实例(所有构造函数均具有相同的签名)。所以我想要类似的东西:

abstract class Foo {

}

class Bar1 extends Foo {
    constructor(someVar) { ... }
}

class Bar2 extends Foo {
    constructor(someVar) { ... }
}

但这不能完成,因为abstract class Foo { public static someAction(someVar) { const self = new this(someVar); } } 是抽象的。这有可能吗?

更新

如果这些类有自己的模板怎么办?

Foo

现在,我希望abstract class Foo<M> { } class Bar1 extends Foo<SomeModel> {...} 知道类型someAction。我尝试过

SomeModel

但是,除非我专门进行public static someAction<A, T extends Foo<A>>(this: new (someVar: any) => T, someVar: any): T { const self = new this(someVar); return self; } ,否则返回的结果不适用于数据类型,即Bar1.someAction<SomeModel>("blah")不知道数据类型

2 个答案:

答案 0 :(得分:6)

您可以为静态方法的this类型添加注释。在这种情况下,this将引用该类,并且为this参数添加注释将使静态方法仅在满足约束的类上可见(在这种情况下,具有单个参数的构造函数存在),这也将有助于我们提取方法在上调用的类的实际实例类型:

abstract class Foo {
  public static someAction<T extends Foo>(this: new (someVar: any) => T, someVar: any): T {
    const self = new this(someVar);
    return self;
  }
}

class Bar1 extends Foo {

  constructor(someVar: any) {
    super();
  }
}

class Bar2 extends Foo {
  constructor(someVar: any) {
    super();
  }
}
let bar1 = Bar1.someAction(0) // of type Bar1
let bar2 = Bar2.someAction(0) // of type Bar2

答案 1 :(得分:0)

经过一番摸索之后,我找到了一种方法来解决您的泛型问题。

关键是不要在基类的扩展约束中使用类型变量但是添加带有类型变量的基类作为返回类型的交集。

在此处使用 any 而不是 T static someAction<A, T extends Foo<any>> 在返回类型上添加 & Foo<A>。< /p>

abstract class Foo<M> {...}

class Bar1 extends Foo<SomeModel> {...}
public static someAction<A, T extends Foo<any>>(
    this: new (someVar: any) => T, someVar: any
): T & Foo<A> {
    return new this(someVar);
}

我在尝试创建用户定义的类型保护时遇到了完全相同的问题,上述相同的技术也解决了这个问题。

public static isThisType<A, T extends Foo<any>>(
    this: new (...args: any) => T, value: unknown
): value is T & Foo<A> {
    return value instanceof this;
}