我目前正在打字稿中碰壁。
基本上,我想从扩展特定抽象类的类中调用静态函数。
我收到以下错误
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 类型,因为它们来自外部库。
答案 0 :(得分:1)
您正在尝试调用 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中调用这个方法的实现。
答案 1 :(得分:1)
你就在附近!看看你对 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
(或任何静态方法/属性),它的工作方式相同每次!