在将属性从一个对象复制到另一个对象时,如何让TypeScript理解所提供的键实际上属于目标对象?
interface Example {
value: number
dontUpdate: string
}
const a: Example = { value: 1, dontUpdate: 'a' }
const b: Example = { value: 2, dontUpdate: 'b' }
Object.keys(b).forEach(key => {
if (key === 'dontUpdate') return
a[key] = b[key]
// ^ Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Example'.
})
for (let key in b) {
if (key === 'dontUpdate') continue
a[key] = b[key]
// ^ Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Example'.
}
for (let key in b) {
if (b.hasOwnProperty(key) && key !== 'dontUpdate') {
a[key] = b[key]
// ^ Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Example'.
}
}
答案 0 :(得分:0)
不保证对象仅具有您在界面中分配的键。接口通常是键的子集。
请记住,TypeScript被编译为JavaScript。接口在JavaScript中不存在。无论您的界面是什么样,对象上的任何键都会被复制。
这就是为什么您会收到此错误的原因。如果要复制特定的密钥,则必须对每个密钥进行测试。
if(key === 'value') a[key] = b[key] // no error
否则,您可以将它们强制转换为任何类型,并了解它不仅会复制界面中的键,还会复制对象上的所有键。
(a as any)[key] = (b as any)[key]
答案 1 :(得分:0)
如果只想让TypeScript编译器理解您正在访问该对象的属性,则可以使用keyof运算符 https://www.typescriptlang.org/docs/handbook/2/types-from-extraction.html#the-keyof-type-operator
如果要在两个不同的对象中访问相同的属性,要将一个属性复制到另一个对象中,则仍可以通过以下方式使用keyof运算符:
interface Example {
value: number;
dontUpdate: string;
somethingElse: boolean;
}
const a: Example = { value: 1, dontUpdate: 'a', somethingElse: true }
const b: Example = { value: 2, dontUpdate: 'b', somethingElse: false }
const copyProp = <T extends keyof Example>(source: Example, target: Example, prop: T): void => {
target[prop] = source[prop];
}
Object.keys(a).forEach((key) => {
if (key === 'dontUpdate'){
return;
}
// Copy the property key, from object 'a' to object 'b'
copyProp(a, b, key as keyof Example);
})
console.log(b);
其中扩展keyof 表示从 keyof
获得的属性之一如果只想将一个对象复制到另一个对象,则可以使用散布运算符:
const copy = {
...source
};
如果要复制没有特定属性的整个对象,则可以将散布运算符与解构运算符一起使用:
const { dontUpdate, ...copy } = source;