gpt4 book ai didi

javascript - 如何在基类代码内引用 `this.constructor` 上的静态属性?

转载 作者:行者123 更新时间:2023-12-03 04:46:03 25 4
gpt4 key购买 nike

我有这样的 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 将是 Foo,并且 StyleableComponent 类需要查看 Foo.style .

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

最佳答案

静态属性与实例属性继承

如果你想从子类中读取静态属性,你可以通过3种方式来实现。更多详细信息,你可以参见测试部分。

  • 因为Object.getPrototypeOf(..)的返回类型是any,所以可以直接访问style,例如:

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

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

    declare global{
    interface Function{
    style:any;
    }
    }

    someMethod() {
    return this.constructor.style;
    }

你也可以用实例属性替换静态属性来实现。如果你想读取子类的 style 属性,你必须在构造函数中定义该属性,然后子类可以选择通过传递定义其样式父类(super class)的 style 或根本不使用。例如:

constructor(protected style:any="default"){
}

有趣的是,除了 style 属性之外,子类的行为都是相同的。在设计 View 中,如果使用静态样式属性,则必须定义另一个子类来实现它,这往往会导致许多子类具有不同的样式。但是当使用实例属性 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");
}

测试

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

关于javascript - 如何在基类代码内引用 `this.constructor` 上的静态属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42869737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com