值得使用reduce
代替forEach
在这种情况下:
interface IMixed {
a: number;
b: string;
c: boolean;
}
const foo: IMixed = { a: 1, b: 'one', c: true };
const bar: IMixed = { a: 2, b: 'two', c: false };
(Object.keys(foo) as Array<keyof IMixed>)
.reduce((acc, elem) => ({
...acc,
[elem]: bar[elem]
}), foo);
操场
突变在 TypeScript 中效果不佳。
查看相关问题:first, second, third, forth and my article
UPDATE
(Object.keys(foo) as Array<keyof IMixed>).forEach(k => {
foo[k] = bar[k]; // error
});
你这里有一个错误,因为forEach
也reduce
是动态的。bar[k]
是一个联盟number | string | boolean
, 也foo[k]
。这意味着在循环内部可以分配foo['a'] = foo['c']
。这两个值都是有效的,因为我们期望一个并集number | string | boolean
但这也是不安全的。这就是 TS 禁止这种行为的原因。
从另一方面,reduce
有效,因为我们创建了扩展的新对象IMixed
而不是变异
UPDATE
为了能够变异foo
你需要添加indexing
to IMixed
界面:
type IMixed= {
a: number;
b: string;
c: boolean;
[prop: string]: number | boolean | string
}
const foo: IMixed = { a: 1, b: 'one', c: true };
const bar: IMixed = { a: 2, b: 'two', c: false };
(Object.keys(foo) as Array<keyof IMixed>).forEach(k => {
foo[k] = bar[k];
});
操场