我想循环遍历类的属性以生成json表示。
Object.keys(this).forEach((key: keyof MyElement)
总是会抛出错误:
Argument of type '(key: "name" | "toJSON") => void' is not assignable to parameter of type '(value: string, index: number, array: string[]) => void'.
Types of parameters 'key' and 'value' are incompatible.
Type 'string' is not assignable to type "name" | "toJSON"'.
我该如何解决这个问题?
这是班级。
export class MyElement {
private _name: string = '';
get name(): string {
return this._name;
}
set name(value: string) {
this._name = value;
}
public toJSON = (): Object => {
let json = {};
Object.keys(this).forEach((key: keyof MyElement) => { // Error: TS2345: Argument of type '(key: "name" | "toJSON") => void' is not assignable to parameter of type '(value: string, index: number, array: string[]) => void'.
// Types of parameters 'key' and 'value' are incompatible. Type 'string' is not assignable to type "name" | "toJSON"'.
const val = this[key];
if (typeof val !== "function") {
let newKey = key[0] === '_' ? key.slice(1) : key;
json[newKey] = val;
}
});
return json;
}
}
答案 0 :(得分:1)
将lambda的签名更改为与forEach
签名兼容的内容:
Object.keys(this).forEach((key: string) => {
// ...
})
根据您显示的代码,使用人工key: keyof MyElement
并没有什么好处,所以只需使用TypeScript会喜欢的签名。
答案 1 :(得分:0)
问题是编译器无法知道forEach
返回的唯一键也是MyElement
的键。例如,您可以定义一个扩展MyElement
并具有其他键的新类,或者您可以使用Object.assign()
更新它。
因此,当您尝试访问forEach
时,必须使this[key]
获取字符串参数并执行适当的转换(否则,如果您设置了--noImplicitAny
编译器选项,则会收到错误下标的结果是隐式any
)。此外,json
还需要一个索引签名,以便为其分配任意属性。
public toJSON = (): Object => {
let json: { [key: string]: string } = {};
Object.keys(this).forEach((key: string) => {
const val = (this as any)[key];
if (typeof val !== "function") {
let newKey = key[0] === '_' ? key.slice(1) : key;
json[newKey] = val;
}
});
return json;
}