如何在 TypeScript 中为类属性动态分配值

Posted

技术标签:

【中文标题】如何在 TypeScript 中为类属性动态分配值【英文标题】:How to dynamically assign value to class property in 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);

【问题讨论】:

【参考方案1】:

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

您需要以某种方式向key 添加类型注释,seems not to be problematic 在for .. 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];
        
    

【讨论】:

以上是关于如何在 TypeScript 中为类属性动态分配值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeScript 中为对象动态分配属性?

在使用 EF 期间如何在 c# 中为类添加额外的属性

在 TypeScript 中声明动态添加的类属性

如何在TypeScript中定义Singleton

如何在C中为char**动态分配内存

在 Apigee 中,如何使用 AccessEntity 策略以及稍后在 Javascript 中为开发人员获取自定义属性值?