如何在基类代码中引用`this.constructor`的静态属性?

时间:2017-03-18 02:16:00

标签: javascript generics typescript

我有这样的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)
    }
}

和TypeScript抛出此错误:

ERROR in ./src/StyleableComponent.ts
(11,38): error TS2339: Property 'style' does not exist on type 'Function'.

但是,显然,您可以看到在类定义中声明了static style: any

那么,我们如何正确使用this.constructor?请注意,this.constructor可以是扩展StyleableComponent的类的构造函数,因此this.constructor可能不是=== StyleableComponent,但它应该具有style属性,因为它从StyleableComponent延伸。

例如,

interface P {...}
interface S {...}
class Foo extends StyleableComponent<P,S> {...}

console.log(new Foo)

^ this.constructor将为FooStyleableComponent类需要查看Foo.style

那我该怎么做?我是否需要以某种方式使用额外的模板类型参数?

1 个答案:

答案 0 :(得分:1)

静态属性V.S实例属性继承

如果你想从子类读取静态属性,你可以用3种方式来做。有关详细信息,你可以看到测试部分。

  • 因为Object.getPrototypeOf(..)的返回类型为any,因此您可以直接访问样式,例如:

    someMethod() {        
      let style = Object.getPrototypeOf(this).constructor.style;          
    }
    
  • 因为this.constructor的返回类型是Function,所以您必须先将其分配给any变量,例如:

    someMethod() {        
      let cotr:any=this.constructor;
      let style = cotr.style;          
    }
    
  • 因为Function是一个接口,您可以在typescript中展开它,例如:

    declare global{
      interface Function{
        style:any;
      }
    }
    
    someMethod() {        
      return this.constructor.style;         
    }
    

并且您也可以使用instance属性替换static属性。如果您想要读取子类style属性,则必须在构造函数上定义属性,然后子类可以通过传递{{{}来定义其样式。 1}}到超类或根本没有。例如:

style
有趣的是,除了constructor(protected style:any="default"){ } 属性之外,子类行为都是相同的。在设计视图中,如果使用静态样式属性,则必须定义另一个子类来实现它,这将倾向于许多子类与差异样式。但是当使用实例属性style时,您可以通过仅style通过可选的style来执行此操作。例如:

style

并且您也可以通过传递子类的构造函数中的let bar=new Bar();//use parent's style let baz=new Bar(null,null,"baz");//use it owned style 来拒绝其他人传递他们的样式。例如:

style

测试

constructor(){
  super("style");
}