繁体   English   中英

使用装饰器中的prototype / Access基类属性访问派生类中的基类属性

[英]Accessing base class properties in derived class using prototype/Access base class properties in the decorator

我正在使用打字稿,我正在为我的一个角度类写一个自定义装饰器。 我想访问子类装饰器中的基类方法。 或者使用子类原型访问基类方法。 有没有办法做到这一点? 问题详细解释如下。

脚本

我有一个基类就像

export class Base {
    public init() {
        console.log('My base class function');
    }
}

我有一个扩展这个基类的派生类

export class Child extends Base {

}

我想做什么

我正在尝试为派生类编写类似的装饰器

@TestDecorator(['init'])
export class Child extends Base {

}

这将从基类调用init方法

问题是什么

为了完成上述场景,我编写了类似下面的代码

export function Tool<T extends Base>(methods: any[]) {
    return function (target: Function) {
        methods.forEach((item) => {
            if (item === 'init') {
                target.super.init() // Stuck here
            }
        })
    }
}

我不明白如何使以下行工作

target.super.init() // Stuck here

请帮我解决这个问题。 我被卡住了。 谢谢

我相信你正在寻找这样的东西:

export function Tool<T extends Base>(methods: any[]) {
    return function (target: Function) {
        return class extends target {
            constructor(...args: any[]) {
                super(...args)
                methods.forEach((item) => {
                    if (item === 'init') {
                        super.init( );
                    }
                })
            }
        }
    }
}

为了扩展Paulpro的答案,由于装饰器函数返回了它正在装饰的类的构造函数的替代,它必须维护原始原型。

在以下示例中,由于TestDecorator<Base>缺少init()方法而导致错误。

打字稿游乐场演示

class Base {
  public init() {
    console.log('My base class function');
  }
}

function TestDecorator<T extends Base>(methods: any[]) {
  return function (target: any) {
    return class extends target {
      constructor(...args: any[]) {
        super(...args)
        methods.forEach((item) => {
          if (item === 'init') {
            super.init( );
          }
        })
      }
    }
  }
}

@TestDecorator(['init'])  // Error: Property 'init' is missing in type 'TestDecorator<Base>.(Anonymous class)' but required in type 'Child'.
class Child extends Base {

}

let c = new Child();

修正了装饰者

function TestDecorator<T extends Base>(methods: any[]) {
  return function (target: any) {
    return class extends target {
      init() {}  // Define init()

      constructor(...args: any[]) {
        super(...args)
        methods.forEach((item) => {
          if (item === 'init') {
            super.init( );
          }
        })
      }
    }
  }
}

类装饰器

如果类装饰器返回一个值,它将使用提供的构造函数替换类声明。

注意:如果您选择返回新的构造函数,则必须注意维护原始原型。 在运行时应用装饰器的逻辑不会为您执行此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM