Typescript:调用具有“this”参数的静态函数

问题描述 投票:0回答:2

我目前在打字稿中碰壁了。

基本上,我想从扩展特定抽象类的类中调用静态函数。

我收到以下错误

The 'this' context of type 'typeof A' is not assignable to method's 'this' of type 'AStatic<AStatic<unknown>>'. Cannot assign an abstract constructor type to a non-abstract constructor type.

这里是Typescript Playground

的链接

这是代码:

type AStatic<S extends A> = { new(): S };

abstract class A {
  static callStatic<S extends AStatic<S>>(this: AStatic<S>) {
    console.log('hey')
  }
}

class B extends A {
}


class D extends A {
}

class C {
  aType: typeof A;
  constructor(type: typeof A) {
    this.aType = type;
    this.aType.callStatic(); // error is here
  }
}

const c = new C(B);
const c_2 = new C(D);

我设法使其在打字稿中构建的唯一方法是传递

any
,而不是
typeof A
。真遗憾,因为我的 IDE 不支持 A 的功能。

请注意,我无法控制 A 类和 AStatic 类型,因为它们来自外部库。

javascript typescript constructor this static-methods
2个回答
2
投票

你很接近!看看你对

A
的伪定义:

abstract class A {
  static callStatic<S extends AStatic<S>>(this: AStatic<S>) {
  //                                      ^^^^^^^^^^^^^^^^
  //           the `this` parameter must be type AStatic<A>

看着

AStatic

type AStatic<S extends A> = { new(): A };
//                            ^^^^^ - type must have a constructor, 
//                                      which rules out abstract classes.

这排除了

typeof A
作为
this
参数,因为它是
abstract
。我们可以尝试直接使用
AStatic

class C {
  aType: AStatic<A>;
  constructor(type: AStatic<A>) {
    this.aType = type;
    this.aType.callStatic();
    //         ^^^^^^^^^^ - Property 'callStatic' does not exist on type 'AStatic<A>'
  }
}

但是

callStatic
没有定义在
AStatic
上。解决方案是交叉类型:

class C {
  aType: AStatic<A> & typeof A
  constructor(type: AStatic<A> & typeof A) {
    this.aType = type;
    this.aType.callStatic() // works!
  }
}

正如 MunsMan 指出的那样,除非你在派生类型上重写

callStatic
,否则根本不需要传递
typeof A

const c = new C(B);
c.callStatic(); // hey
B.callStatic(); // hey
D.callStatic(); // hey

换句话说,只要您有

A
的非抽象版本,您就可以在该类型上调用
callStatic
(或任何静态方法/属性),并且每次都会以相同的方式工作!


2
投票

您正在尝试调用 A 的显式实例,这是不必要的。

type AStatic<S extends A> = { new(): A };

abstract class A {
    static callStatic<S extends AStatic<S>>(this: AStatic<S>) {
        console.log('hey')
    }
}

class B extends A {

}

class C {
    aType: typeof A;
    constructor(type: typeof A) {
        this.aType = type;
        B.callStatic()
    }
}

const c = new C(B);

因为callStatic方法是静态的,所以你可以直接在B中调用该方法的实现。

© www.soinside.com 2019 - 2024. All rights reserved.