简体   繁体   English

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

[英]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? 我是否需要以某种方式使用额外的模板类型参数?

Static Property VS Instance Property Inheritance 静态属性VS实例属性继承

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");
}

Tests 测验

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.

相关问题 通过构造函数调用使用this.constructor来访问静态属性时,是否存在兼容性问题? - Are there compatibility issues when using this.constructor from with a constructor invocation to access static properties? JavaScript Class 构造函数中的属性 - JavaScript Class properties inside constructor JS:this.constructor 简写(从非静态调用 static 方法) - JS: this.constructor shorthand (calling static methods from non-static) 如何为在构造函数中声明的 class 属性获取智能感知(在 vscode 中) - how to get intellisense (in vscode) for class properties declared inside constructor 如何将 object 作为参数传递并在构造函数中引用它 - How to pass an object as an argument and reference it inside a constructor 如何在 Javascript 中覆盖基类构造函数 - How to override a base class constructor in Javascript 为什么我无法将构造函数中定义的实例属性/属性访问到 static 方法中 - why i am unable to acces the instance properties / properties defined inside the constructor into static method static 方法内的 JSON.parse() 如何访问 Z686155AF70C160A0F6EZD8 中的 class 属性? - How the JSON.parse() inside the static method is accessing class properties in JavaScript? 是什么( <typeof className> this.constructor)在打字稿中意味着什么? - what does (<typeof className>this.constructor) mean in typescript? JavaScript new this.constructor();元素列表后面的=> SyntaxError:missing] - JavaScript new this.constructor(); => SyntaxError: missing ] after element list
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM