在打字稿中覆盖 children 的静态字段

Overriding static fields for children in typescript

我有一个包含静态 URL 的抽象 class 并使用该静态 URL 实现功能。 children 应该覆盖 class A.

中的静态 URL

但我还是希望 children 使用他们提供的功能 parent class A 使用 [=] 的静态覆盖 URL 16=] class。有没有办法在 Typescript 中做到这一点?

interface IState {
    cashflowToPost?: CashflowObject;
    cashflowList: CashflowObject[];
}
export default abstract class CashflowListView extends React.Component<{}, IState> {
    static cashflowObject : CashflowObject;
    static getURL : URL;

    
    callApi() {
        try {
            axios.get(CashflowListView.getURL.toString()).then(response => {
                console.log("called Api");
                this.setState({cashflowList: response.data});
            })
        } catch {
            console.log("failed to call api!")
        }
    }
    


    componentDidMount() {
        this.callApi();
    }

    
}

But I'd still like the children to use the functions provided by their parent class A to use the static overridden URL of the child class.

子实例当然可以访问父实例中的方法 class,但是如果父实例的方法访问静态 属性,从实例调用它将会失败:

class A {
  static getURL = 'http://example.com';
  
  aMethod() {
    console.log('A.aMethod() getURL:', getURL);
  }
}

class B extends A {
  static getURL = 'http://example.com/BClass';
}

const bInstance = new B();
bInstance.aMethod(); // ReferenceError: Can't find variable: getURL

虽然您不能“覆盖”class 的静态变量,但您可以这样做:

class A {
  static getURL = 'http://example.com/AClass';
  
  // make the method static and pass in url
  static aMethod(url) {
    console.log('aMethod() url:', url);
  }
}

class B extends A {
  static getURL = 'http://example.com/BClass';
}

console.log('A.getURL:', A.getURL);
A.aMethod(A.getURL);

console.log('B.getURL:', B.getURL)
B.aMethod(B.getURL);

但是由于 OP 想要重用一个引用静态 属性 (getURL) 和实例 属性 (this) 的实例方法,一个不同的需要策略。

解决方案:从 Class 构造函数

访问静态 属性

幸运的是,我们可以利用 static property can be referenced from the instance's class constructor:

   thisURL = this.constructor.getURL;

this.constructor.getURL 引用实例 class 的静态 属性 getURL(不是父项的 class)。

class A {
  static getURL = 'http://AClassURL';

  aInstanceMethod() {
    // `this.constructor.getURL` references the instance's class
    this.result = `result obtained using ${this.constructor.getURL}`;
  }
}

class B extends A {
  static getURL = 'http://BClassURL';
}


const aInstance = new A();
aInstance.aInstanceMethod();

const bInstance = new B();
bInstance.aInstanceMethod();


document.querySelector('pre').innerText =
  `A.getURL = ${A.getURL}
B.getURL = ${B.getURL}

aInstance: ${JSON.stringify(aInstance, null, 2)}

bInstance: ${JSON.stringify(bInstance, null, 2)}`;
<pre></pre>

好吧,在我自己开始搜索之前,我认为这是不可能的。这已经在这里得到回答:Access child class' static members from base class

abstract class Base {
    static url: string = "hello.com";

    log() {
        const thisConructor = this.constructor as typeof Base;
        console.log('Do it>>>', thisConructor.url);
        // => Make axios call with "thisConructor.url"
    }
}

class Child extends Base {
    static url: string = "hello1.com";
}

const c = new Child();
c.log(); // => "hello1.com"