在TypeScript中获取调用属性的名称

问题描述 投票:2回答:1

我想创建一组我将使用的泛型方法,而不是支持属性的字段。我需要在setter中做一些常规的东西(在Angular 5中调用事件发射器),我不想每次都写它。

我试过这三件事:

  1. 我可以将属性名称作为字符串传递,但我想避免这种情况。
  2. 我也尝试使用Error.stack,但堆栈跟踪的解析在不同的浏览器中会有所不同,我不喜欢这样。
  3. 当我尝试使用arguments.callee.caller时,我得到:'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

还有其他建议吗?

以下用法示例。请注意// somehow get calling property name评论。在这个例子中,我希望有一个返回"myProperty"字符串的代码。

class ApplicationComponent {
    private readonly properties = new Map<string, any>();

    protected getProperty<T>(): T {
        const propertyName = // somehow get calling property name
        return <T>this.properties[propertyName];
    }

    protected setProperty<T>(value: T): void {
        const propertyName = // somehow get calling property name
        const oldValue = <T>this.properties[propertyName];

        if (oldValue === value) {
            return;
        }

        this.properties[propertyName] = value;

        const eventEmitter = this[`${propertyName}Change`];
        if (eventEmitter != null && eventEmitter instanceof EventEmitter) {
            eventEmitter.emit(value);
        }
    }
}

class SomeComponent extends ApplicationComponent {
    get myProperty(): SomeType {
        return this.getProperty();
    }

    set myProperty(value: SomeType) {
        this.setProperty(value);
    }

    readonly myPropertyChange = new EventEmitter<SomeType>();
}
javascript angular typescript properties
1个回答
1
投票

详细程度有帮助,因为在生产中这种情况下不可能可靠地获取属性名称。如果getPropertysetProperty应该影响特定属性,则它们应该接受属性名称作为参数。

这是property decorators的一个很好的用例。装饰器接受类prototype对象和属性名称。然后它可以将属性描述符设置为它需要的任何内容

function property(proto, key) {
  Object.defineProperty(proto, key, {
    get() {
      return this.properties[key]
    },
    set(val) { ... }
  });
}

class SomeComponent extends ApplicationComponent {
  @property
  myProperty: SomeType;
}
© www.soinside.com 2019 - 2024. All rights reserved.