如何将实例变量传递给打字稿装饰器参数?

Posted

技术标签:

【中文标题】如何将实例变量传递给打字稿装饰器参数?【英文标题】:How to pass an instance variable into typescript decorator arguments? 【发布时间】:2016-04-17 19:31:47 【问题描述】:

How to implement a typescript decorator? 是一个关于如何在 typescript 中使用装饰器的好例子。

考虑到以下情况,

class MyClass 
    @enumerable(false)
    get prop() 
        return true;
    

    @property(required: true) //here pass constant is no issue
    public startDateString:string;

    @property(afterDate: this.startDateString) //how to pass startDateString here?
    public endDateString:string;


function enumerable(isEnumerable: boolean) 
    return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => 
        descriptor.enumerable = isEnumerable;
        return descriptor;
    ;

我尝试了所有方法,但似乎无法将 startDateString 传递给装饰器参数。 startDateString 可以是变量、函数和引用。

【问题讨论】:

这可能取决于您需要使用传入值的方式何时。我知道您需要将startDateString 的... errrr... instance value 传递给应用于endDateString 的装饰器,但是您打算做什么 i> 在装饰器中使用它?根据具体情况,可以通过装饰器获取实例成员。 【参考方案1】:

你试图做的事情是不可能的。

装饰器在类被声明时被调用,此时没有实例可以传递给装饰器。

例如,使用以下代码:

class MyClass 
    startDateString: string;
    @property( afterDate: this.startDateString )
    endDateString: string;

let myClass = new MyClass();
    MyClass 已声明。 装饰器在MyClass 上运行。此时不存在要传入的实例,并且装饰器参数中的 this 指的是全局对象,而不是实例。 调用new MyClass() 并创建实例。这一步不调用装饰器。这已经发生了。

查看编译后的 javascript 以供参考:

var MyClass = (function () 
    // -- 1 --
    function MyClass() 
    
    // -- 2 --
    __decorate([
        // see here... `this` is equal to the global object
        property( afterDate: this.startDateString )
    ], MyClass.prototype, "endDateString", void 0);
    return MyClass;
)();
// -- 3 --
var myClass = new MyClass();

请注意,使用this.startDateString 不会在此处引发编译错误,因为this 的类型为any

所以这里试图通过传入实例属性来完成的事情是没有意义的,也是不可能的。

您可以做的是将startDateString 设为静态,然后像这样传递它:@property( afterDate: MyClass.startDateString )

【讨论】:

谢谢。但就我而言,作为类变量不能是静态的。它必须是一个实例变量。 @new2cpp 您可以做的一件事是传入一个字符串或一个函数,该函数被传递一个类的实例并返回属性值。类似于 afterDate: "startDateString" afterDate: (instance: MyClass) =&gt; instance.startDate 。一旦有了类的实例,您就可以稍后使用此信息从属性中获取值。这是一个 hacky 解决方案,但它是一种让所有查看代码的人感到困惑的好方法。【参考方案2】:

您无法从属性定义访问对象属性。

定义属性时调用装饰器。

您可以在访问属性时使用 getter 或 setter 来获得控制权。

【讨论】:

以上是关于如何将实例变量传递给打字稿装饰器参数?的主要内容,如果未能解决你的问题,请参考以下文章

打字稿装饰器与类继承

打字稿装饰器不能使用箭头函数

如何将装饰器中的变量传递给装饰函数中的函数参数?

Vue Prop 未定义,和/或不能在 v-for 上使用。使用打字稿和装饰器

将变量传递给注入的服务以用作装饰器参数

带有箭头功能的打字稿装饰器