我正在尝试建立一个动态构建过滤字符串的类。为此,我创建了以下类:
export class UrlBuilder<T extends BaseSpalten> {
private spalten: T;
....
public filterData(config: (spalten: T, addParameter: (key: string, value: string) => void,
addParameterListe: (key: string, value: string[]) => void) => void): UrlBuilder<T> {
config(this.spalten, this.addQueryParameter, this.addQueryParamterList);
return this;
}
....
}
但是现在我遇到了一个问题,即“ BaseSpalten”类和扩展类是静态类:
export class BaseSpalten {
public static AenderungVersion: string = 'AenderungVersion';
public static Dirty: string = 'Dirty';
}
但是我需要在config函数中使用类的属性,以确保获得有效的过滤器。我如何将对静态T的引用传递给config函数?
据我所知,我们可以将您的问题简化为以下问题。给定具有某些静态属性的类层次结构:
class BaseClass {
public static staticPropBase: string = 'foo';
}
class SubClass extends BaseClass {
public static staticPropSub: string = 'bar';
}
我们如何从类的实例访问那些静态属性?在运行时,这实际上很简单。所有JavaScript对象都有一个constructor
property,它引用创建它的构造函数。因此,具有所有静态属性的constructor
将为(new SubClass()).constructor
。
因此您可以编写此代码,它将起作用:
SubClass
但是问题是TypeScript编译器不满意。它没有意识到const subclass = new SubClass();
console.log(subclass.constructor.staticPropBase); // TS error, but "foo" at runtime
console.log(subclass.constructor.staticPropSub); // TS error, but "bar" at rntime
是subclass.constructor
构造函数。关于SubClass
的所有知识就是它是subclass.constructor
。确实是这样(类构造函数are函数),但不够具体以至于无济于事。
但是等等,TypeScript编译器知道难道Function
的类型是(new SubClass()).constructor
本身吗?是的,大概是typeof SubClass
。 a longstanding open issue, see microsoft/TypeScript#3841为什么不自动执行此操作是因为子类构造函数不需要是其超类构造函数的有效子类型。在以下情况下:
The stated reason
即使实例类型class A {
a: string = "a";
constructor() { } // no param
}
class B extends A {
b: number;
constructor(b: number) { // one param
super();
this.b = b;
}
}
是实例类型B
的子类型,其构造函数A
也是not子类型typeof B
(因为typeof A
的构造函数需要一个参数,而B
则不是):
A
[如果TypeScript编译器自动为const a: A = new B(123); // okay
const _A: typeof A = B; // error! Type 'typeof B' is not assignable to type 'typeof A'.(2322)
提供A
类型的constructor
属性,并且typeof A
为B
类型的constructor
属性,则实例类型typeof B
将不再是有效的子类型B
的值,而子类型的A
模型将失败。
Blecch。但是,如果TS可以比extends
做得更好,那肯定会很好。但是,即使他们最终做出了更改,您也会遇到问题[[today。您现在可以做什么?[也许最好的当前解决方法是手动声明您的类实例具有正确类型的Function
属性。由于您的类构造函数为空,因此constructor
是typeof SubClass
的有效子类型,因此不会出现上述问题。 (如果确实出现,则可以使用typeof BaseClass
之类的类型来保留静态属性,但忽略构造函数签名。可根据要求提供更多信息。)
Pick<typeof SubClass, keyof typeof SubClass>
(请注意,对于TS3.7及更高版本,应使用class BaseClass {
declare ["constructor"]: typeof BaseClass; // TS 3.7+
//["constructor"]!: typeof BaseClass; // TS 3.6-
public static staticPropBase: string = 'foo';
}
class SubClass extends BaseClass {
declare ["constructor"]: typeof SubClass; // TS 3.7+
//["constructor"]!: typeof SubClass; // TS 3.6-
public static staticPropSub: string = 'bar';
}
,而对于TS2.7至TS3.6,应使用a declare
property modifier。它们基本上执行相同的操作。根据需要提供更多信息。]
现在,下面的方法就可以了:
declare
否则,您始终可以只使用a definite assignment assertion来禁止编译器的警告:const subclass = new SubClass(); console.log(subclass.constructor.staticPropBase); // okay, "foo" console.log(subclass.constructor.staticPropSub); // okay, "bar"
我个人宁愿强烈键入类定义,但类型断言也将起作用。
好的,希望能有所帮助;祝你好运!
type assertions