我目前在打字稿中碰壁了。
基本上,我想从扩展特定抽象类的类中调用静态函数。
我收到以下错误
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.
的链接
这是代码:
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 类型,因为它们来自外部库。
你很接近!看看你对
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
(或任何静态方法/属性),并且每次都会以相同的方式工作!
您正在尝试调用 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中调用该方法的实现。