【问题标题】:typescript class decorator: typing properties defined in decorator functiontypescript 类装饰器:在装饰器函数中定义的类型属性
【发布时间】:2015-10-23 19:50:30
【问题描述】:

bar 是一个简单的类装饰器,它为类 Foo 添加了一个属性。

function bar(target) {
    target.inDecorator = 'in decorator';
}

@bar
class Foo {
    inClass:string;
    inDecorator:string;
    constructor() {
        this.inClass = 'a string';
    }

    getInClass() {
        return this.inClass;
    }
}

console.log(Foo.inDecorator);
console.log(Foo.prototype.inDecorator);
const foo = new Foo();
console.log(foo.getInClass());
console.log(foo.inDecorator);

唯一导致错误的控制台日志是第一个,Foo.inDecorator,在 ts 1.5.3 中包含它

Property 'inDecorator' does not exist on type 'typeof Foo'.

据我所知,inDecorator 应该定义在 Class Foo 的原型上,并且应该在 Foo 上可用,就好像它是一个静态道具一样。运行生成的 js 文件显示原型访问以及新 foo 对象上的未定义,但是 Foo.inDecorator 正确打印,即使它是错误的来源。为了更清楚,我们得到

in decorator
undefined
a string
undefined

关于如何正确输入/添加静态道具或方法的任何想法?

谢谢!

编辑这个,因为我最初忽略了原型访问,Foo.prototype.inDecorator 不起作用的事实。

【问题讨论】:

    标签: javascript class typescript decorator typeof


    【解决方案1】:

    在装饰器内target 指的是函数——Foo——而不是原型——Foo.prototype

    所以在装饰器中target.inDecorator = ...Foo.inDecorator = ... 相同,而不是Foo.prototype.inDecorator = ...

    这是一种方法:

    interface BarStatic {
        new(): BarInstance;
        inDecorator: string;
    }
    
    interface BarInstance {
        inDecorator: string;
    }
    
    function bar(target: BarStatic) {
        target.inDecorator = 'static';
        // note that prototype will be `any` here though
        target.prototype.inDecorator = 'instance';
    }
    
    @bar
    class Foo {
        static inDecorator: string; // required
        inDecorator: string;        // required
        inClass: string;
    
        constructor() {
            this.inClass = 'a string';
        }
    
        getInClass() {
            return this.inClass;
        }
    }
    
    console.log(Foo.inDecorator);           // static
    console.log(Foo.prototype.inDecorator); // instance
    const foo = new Foo();
    console.log(foo.getInClass());          // a string
    console.log(foo.inDecorator);           // instance
    

    【讨论】:

    • 这确实有效,但似乎有很多多余的代码,而且肯定不直观。如果 inDecorator 与 Foo.inDecorator 相同,为什么它必须在基类上?如果要使用 static newProp = "new string" 在 Foo 上直接添加静态道具,是否也必须以这种奇怪的方式输入?没有办法实现接口而不是扩展类?或者使用静态 inDecorator: string;而是在 Foo 类上?我自己的实验表明没有。感谢您的工作解决方案!只希望typescript有更简洁的方法
    • 太棒了!感谢您解决这个问题!在简单地从装饰器中添加道具的情况下,我想它确实归结为静态 inDecorator: string;就在 Foo 中,如果您不输入接口或添加到原型。我发誓我试过了。 :) 经典继承在这里要干净得多,但我正在尝试编写一个看起来和感觉像 2.0 的 Angular 1.x,它使用组件和视图装饰器来完成大量的指令逻辑。或许有点傻。这些函数还做了很多其他更具体的装饰器工作,只是似乎无法在 ts.properties 中输入道具。谢谢!
    猜你喜欢
    • 2020-06-20
    • 1970-01-01
    • 2019-07-23
    • 2022-08-15
    • 2021-05-17
    • 2019-07-29
    • 2018-07-20
    • 2018-01-31
    • 2017-11-15
    相关资源
    最近更新 更多