【问题标题】:Typescript Decorator with Generic Type具有通用类型的打字稿装饰器
【发布时间】:2018-12-16 18:05:12
【问题描述】:

不适用于以下代码:

function deco<T>(){
    return function(target, key){
        // before
        // target[key] = new Decorated<T>();
        // edited
        Object.defineProperty(target, key, {
            get(){
             return new Decorated<T>();
            }
        });
    }
}

class Decorated<T> {
    set(values: T){
    }
}

class MyDecos {
    @deco<{a: number}>() a;
    @deco<{b: string}>() b;
}

const test = new MyDecos;
test.a.set(); // want to throw error
test.a.set({a: '1'); // want to throw error
test.b.set({b: 1); // want to throw error

泛型有什么问题吗? 助手显示values: any

我想 Test.set 使用来自装饰器的 Generic 的方法

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    装饰器不能改变类的结构,这个限制是设计使然。我们可以使用 mixins 来实现类的突变,如here 所述。

    但是,如果没有更完整的示例,我不确定您为什么不直接使用 Decorated&lt;T&gt; 的实例来实例化该字段。在这种情况下,装饰器版本似乎并没有增加太多:

    class MyDecos {
        a = new Decorated<{ a: number }>();
        b = new Decorated<{ b: string }>();
    }
    
    const test = new MyDecos;
    test.a.set(); // error
    test.a.set({ a: '1'); //error
    test.b.set({ b: 1); //  error
    

    注意您当前的装饰器实现不正确,您将Decorated 分配给targettarget 是类而不是类的实例,因此只有一个Decorated 对象将存在于类的 all 实例中,我猜这是为了保存实例状态,因此实现会导致问题。

    【讨论】:

    • 装饰器使用getter来改变实例怎么样?,我已经尝试过了,然后得到了同样的结果。
    • @styliss 是的,您可以解决创建属性的单一实例问题。这仍然不会改变类的结构,你不能从装饰器中做到这一点,你可以显式地声明类型,但这意味着复制不是很好的类型。再次不确定为什么这必须是一个装饰器,如果你提供一个更完整的例子来看看为什么需要一个装饰器,也许我们可以想出一个更好的解决方案
    • 结果类使用属性键和装饰器的父类,并引用其他装饰属性。 property = new Decorated(this, 'property') => @deco() property
    猜你喜欢
    • 2020-01-17
    • 2016-12-05
    • 2020-01-02
    • 1970-01-01
    • 2023-03-23
    • 2017-04-02
    • 2019-03-25
    • 2017-10-10
    • 2020-01-22
    相关资源
    最近更新 更多