如何在 TypeScript 中動態賦值給類屬性
我想在 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; 遇到問題,錯誤如下:
物件類型的索引簽章隱含具有「any」類型。
我需要改變什麼還是我的方法完全錯誤?
在介面作為建構函數參數時,在建構函數中設置預設屬性也是一個不錯的解決方案。
編輯過:
關於我真的很喜歡的條目,所以我正在使用這段代碼:
//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 添加類型註解,這在 for .. of 迴圈中似乎不是問題。
我認為這個方法不錯,但你需要以稍微不同的方式重寫對屬性的迭代。
順便說一下,我猜你也是針對 ES6(以避免編譯器對 .entries() 抱怨,它看起來像是 ES6 的特性)。它看起來是用於陣列,而不是物件。
編輯:
受到另一個 Stack Overflow 回答的啟發 - 為了使錯誤消失,你可以添加一個 any 類型轉換,像這樣:
(<any>this)[key] = value;
不過,上述關於使用 .entries() 的說法仍然適用。
答案#2
從 TypeScript 2.1 開始,更好的方法是使用 keyof 和映射類型。
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];
}
}
}
