【问题标题】:How to dynamically assign value to class property in TypeScript如何在 TypeScript 中为类属性动态分配值
【发布时间】:2016-12-08 21:57:26
【问题描述】:

我想在 TypeScript 中为 MyClass 动态分配多个属性,因此无需编写多行代码来设置类属性。我写了以下代码:

interface IMy
{
    visible?: boolean;
    text?: string;
}

class MyClass
{
    element: JQuery;

    assing(o: IMy): void
    {
        for (let [key, value] of Object.entries(o))
        {
            if (typeof value !== "undefined")
                this[key] = value;
        }
    }

    get visible(): boolean
    {
        return this.element.is(":visible");
    }

    set visible(visible: boolean)
    {
        this.element.css("display", visible ? "" : "none");
    }

    get text(): string
    {
        return this.element.html();
    }

    set text(text: string)
    {
        this.element.html(text);
    }
}

let t = new MyClass();
t.assign({ visible: true });
//instead t.visible = true;

//or

t.assign({ text: "Something" });
//instead t.text = "something";

//or

t.assign({ text: "Something", visible: false });
//instead t.visible = true; 
//        t.text = "something";

但是,我在this[key] = value; 行有问题,错误:

对象类型的索引签名隐含地具有“任何”类型。

我需要改变什么或者我的方法完全错误?
当接口是构造函数参数时,在构造函数中设置默认属性也是一个很好的解决方案。

已编辑:
关于我真的很喜欢它们的条目,所以我使用了这个代码:

//extensions.d.ts
interface Object
{
    entries<T>(o: any): [string, T][];
    entries(o: any): [string, any][];
}
//exntesion.js !!note js not ts
if (!Object.entries)
{
    Object.entries = function* entries(obj)
    {
        for (let key of Object.keys(obj))
        {
            yield [key, obj[key]];
        }
    };
}

编辑 2:

主要想法是解决重载构造函数的问题,您只能设置所需的属性。
如果其他人发现它可用,这里是完整的代码。

interface IMy
{
    prop1?: boolean;
    prop2?: string;
    prop3?: string;
    prop4?: number;
}

class MyClass implements IMy
{
    prop1: boolean = false;
    prop2: string = "";
    prop3: string = "Something";
    prop4: number = 0;

    constructor(properties: IMy)
    {
        this.assing(properties);
    }

    assing(o: IMy): void
    {
        let that = (<any>this);
        for (let key in o)
        {
            if (o.hasOwnProperty(key))
            {
                let value = (<any>o)[key];
                if (typeof value !== "undefined" && typeof that[key] !== "undefined")
                    that[key] = value;
            }
        }
    }

}

let my1 = new MyClass({ prop1: true });
let my2 = new MyClass({ prop2: "SomeText", prop3: "Anything" });
//I set prop2 and prop3
let my3 = new MyClass({ prop4: 10 });    
//I set prop4 (fourth parameter)

console.log(my1, my2, my3);

【问题讨论】:

    标签: typescript


    【解决方案1】:

    错误本身来自--noImplicitAny 编译器选项。如果你删除它,错误就会消失。但我相信,拥有它并不是一件坏事。

    您需要以某种方式向key 添加类型注释,seems not to be problematicfor .. of 循环中使用。

    我认为这种方法还不错,但是您需要稍微不同地重写对属性的迭代。

    顺便说一句,我假设您也是针对 ES6 的(因为编译器不要抱怨 .entries(),它看起来像 ES6 feature。看起来它是用于数组,而不是对象。

    编辑:

    受另一个 SO answer 的启发 - 要消除错误,您可以向 any 添加演员表,如下所示:

    (<any>this)[key] = value;
    

    上述关于使用.entries() 的内容仍然适用。

    【讨论】:

      【解决方案2】:

      从 TypeScript 2.1 开始,更好的方法是使用 keyof and Mapped Types

      function test()
      {
          const my = new MyClass();
          my.assign({ prop1: 3});
      }
      
      
      type MyClassPartial = {
          [P in keyof MyClass]?: MyClass[P];
      };
      
      class MyClass
      {
          prop1: number;
          prop2: string;
          assign(props: MyClassPartial)
          {
              for (const key of Object.keys(props))
              {
                  this[key] = props[key];
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-06-03
        • 2019-08-23
        • 1970-01-01
        • 1970-01-01
        • 2021-09-29
        • 2020-09-03
        • 1970-01-01
        相关资源
        最近更新 更多