[英]How to reference static properties on `this.constructor` inside base class code?
I have TypeScript (JavaScript) class like this: 我有这样的TypeScript(JavaScript)类:
import * as React from 'react'
export default
class StyleableComponent<PROPS, STATE> extends React.Component<PROPS, STATE> {
protected classes: any
static style: any
someMethod() {
const ctor = this.constructor
console.log(this.constructor.style)
}
}
and TypeScript throws this error: 然后TypeScript抛出此错误:
ERROR in ./src/StyleableComponent.ts
(11,38): error TS2339: Property 'style' does not exist on type 'Function'.
But, obviously, you can see that static style: any
is declared in the class definition. 但是,显然,您可以看到static style: any
在类定义中声明。
So, how do we work with this.constructor
properly? 那么,我们如何正确地使用this.constructor
? Note, this.constructor
can be the constructor of a class that extends StyleableComponent
, so this.constructor
may not be === StyleableComponent
, but it should have the style
property because it extends from StyleableComponent
. 请注意, this.constructor
可以是扩展StyleableComponent
的类的构造函数,因此this.constructor
可能不是=== StyleableComponent
,但是它应该具有style
属性,因为它是从StyleableComponent
扩展而来的。
For example, 例如,
interface P {...}
interface S {...}
class Foo extends StyleableComponent<P,S> {...}
console.log(new Foo)
^ this.constructor
will be Foo
, and the StyleableComponent
class needs to look at Foo.style
. ^ this.constructor
将是Foo
,而StyleableComponent
类需要查看Foo.style
。
So how do I do this? 那么我该怎么做呢? Do I need to use a extra template type parameter somehow? 我是否需要以某种方式使用额外的模板类型参数?
If you want read static property from subclass,you can do it with 3 ways.for more details you can see Test section. 如果要从子类中读取静态属性,则可以通过3种方法来实现。有关更多详细信息,请参见“ 测试”部分。
because Object.getPrototypeOf(..)
's return type is any
, so you can access style directly,for example: 因为Object.getPrototypeOf(..)
的返回类型是any
,所以您可以直接访问样式,例如:
someMethod() { let style = Object.getPrototypeOf(this).constructor.style; }
because this.constructor
's return type is a Function
, so you must assign it to a any
variable at first,for example: 因为this.constructor
的返回类型是Function
,所以必须首先将其分配给any
变量,例如:
someMethod() { let cotr:any=this.constructor; let style = cotr.style; }
because Function
is an interface you can expand it in typescript,for example: 因为Function
是一个接口,所以可以用打字稿将其展开,例如:
declare global{ interface Function{ style:any; } } someMethod() { return this.constructor.style; }
and you can also do it with replace static property with instance property instead.if you want read subclass style
property you must define the property on constructor,then the subclass can choose define its style by pass the style
to the superclass or not at all.for example: 如果您想读取子类style
属性,则必须在构造函数上定义该属性,则子类可以通过将style
传递给超类来选择定义其样式,也可以根本不选择。例如:
constructor(protected style:any="default"){
}
the interesting is that the subclass behavior are all the same except the style
property.In design view, if you use the static style properties you must define another subclass to achieve it,this will tends to many subclass with diff styles.but when use instance property style
,you can do it by pass the style
with optional for different style
only.for example: 有趣的是,除了style
属性外,子类的行为都相同。在设计视图中,如果使用静态样式属性,则必须定义另一个子类来实现它,这会导致许多子类具有diff样式。但是在使用实例时物业style
,你可以做到这一点通过传递style
可选不同的style
only.for例如:
let bar=new Bar();//use parent's style
let baz=new Bar(null,null,"baz");//use it owned style
and you can also reject others to pass their style by pass the style
in constructor of the subclass.for example: 您还可以拒绝其他人通过在子类的构造函数中传递style
来传递其样式,例如:
constructor(){
super("style");
}
import * as React from 'react';
declare global {
interface Function {
style: any
}
}
describe('static inheritance', () => {
class StyleableComponent<P, S> extends React.Component<P, S> {
protected classes: any;
static style: any;
constructor(props?: P, context?: any, public style: any = "default") {
super(props, context);
}
someMethod() {
//dangerous if subclass not define static style property
//todo:the 1st approach
// let style = Object.getPrototypeOf(this).constructor.style;
// return style;
//todo:the 2nd approach
// let cotr: any = this.constructor;
// return cotr.style;
//todo:the 3nd approach,you must declare style in Function interface
return this.constructor.style;
}
}
class Foo extends StyleableComponent<any, any> {
static style = "foo";
constructor(props?: any, context?: any) {
super(props, context, Foo.style);
}
}
class Bar extends StyleableComponent<any, any> {
}
test('access style from subclass', function () {
let foo = new Foo();
expect(foo.someMethod()).toBe(Foo.style);
});
test('return undefined if subclass not define style', function () {
let bar = new Bar();
expect(bar.someMethod()).toBeUndefined();
});
test('replace static style with instance property', function () {
let foo = new Foo();
let bar = new Bar();
let baz = new Bar(null, null, "baz");
expect(foo.style).toBe("foo");
expect(bar.style).toBe("default");
expect(baz.style).toBe("baz");
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.