2016-08-03 11 views
4

クラスプロパティを設定するために複数行のコードを記述する必要がないように、TypeScriptのMyClassに複数のプロパティを動的に割り当てる必要があります。私は、エラーのある行this[key] = value;で問題を抱えている、TypeScriptのクラスプロパティに値を動的に割り当てる方法

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"; 

しかし:私は、次のコードを書いた

Index signature of object type implicitly has an 'any' type.

私は何を変更する必要があるか、私のアプローチは完全に間違っていますか?
これは、interfaceがコンストラクタパラメータのときにコンストラクタのデフォルトプロパティを設定するための良い解決策にもなります。

編集:
私は本当に、私はこのコードを使用していますそれらを言っていたエントリについて:

//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); 

答えて

5

エラー自体は--noImplicitAnyコンパイラオプションから来ています。それを削除すると、エラーは消えてしまいます。しかし、私は信じており、それは悪いことではありません。

keyに何らかの形の注釈を追加する必要があります。seems not to be problematicfor .. ofループです。

私はアプローチが悪くないと思いますが、プロパティに対して少し異なる方法で書き換えを書き直す必要があります。

余談として

は、私はあなたがES6をターゲットalse(コンパイラのES6 featureのように見えた、およそ.entries()文句を言うしないようにしていると仮定し、それは配列ではなく、オブジェクトのためだように見えます

EDIT:。。

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

.entries()の使用についての上記が適用され、あなたがエラーが離れて行くようにするには、そのように、anyにキャストを追加することができます - 別のSO answerに触発さ

gh。

1

From 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]; 
     } 
    } 
} 

You get some intellisense

関連する問題